Search code examples
wpfvb.netbindinglistboxsortedlist

Bind a SortedList to ListBox WPF


I'm converting an older .NET WinForms app to WPF. It uses a SortedList:

Dim MyCol as New System.Collections.SortedList(New CaseInsensitiveComparer)

It fills a ListBox in the form by iterating the list, i.e. no data binding.

For Each p In MyCol.Values
    lstBox.Items.Add(p.Name, False)
Next

It's nice because the items appear in the list sorted. Also, because it contains Key,Value pairs, you can instantly get a desired object from the list, or see if it is in the list at all:

If MyCol.Contains("the key") ...

myObject = MyCol("the key")
Debug.Print(myObject.Name)

I do this a LOT in the app, so the 'random access' nature of the SortedList is very important for performance.

So, fast forward to WPF, I need to bind my ListBox to MyCol, but would like to keep it as a SortedList, if possible. How can I bind it?

Edit: To clarify further, I am trying to do it right and want to use MVVM. And ideally I'd bind an ObservableCollection(of myClass) to the ListBox, and use Linq to sort and to query for a particular item. But then I've lost the 'random access' that I had with the SortedList, and I fear this would be a significant performance hit. But I haven't been able to figure out how to convert the SortedList to an ObservableCollection (I'm good, but not super-advanced), so I posted this question to explore if it's possible to stick with the SortedList first, before abandoning it for something else.

What I ended up doing, at least for starters:

In my ViewModel, I have a dependency property of type System.Collections.ICollection. Let's call it MyColProperty.

Once MyCol is populated, I assign it to the property like this. (SortedList.Values is of type System.Collections.ICollection).

MyColProperty = MyCol.Values

In the XAML, the ListBox binds to it like this:

<ListBox ItemsSource="{Binding MyColProperty}" DisplayMemberPath="Name"></ListBox>

And that works to display the Name property of my objects in the MyCol SortedList. So it's sort-of MVVM, though it's not an observable collection. I'll have to see how far I can take it with that short-coming, and then make a decision whether to switch to a true ObservableCollection, or if this will do.

Thanks very much, and hope it helps someone who comes across it. Sandra


Solution

  • one way would be to simply set the SortedList as ItemsSource for the WPF ListBox and use the Name Property as DisplayMemberPath.

    lstBox.ItemsSource = MyCol;
    lstBox.DisplayMemberPath = "Name";
    

    nervertheless you should also look into MVVM and Binding when doing WPF now :)