0

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

Sandra
  • 608
  • 2
  • 11
  • 23
  • possible duplicate of [CollectionViewSource Use Question](http://stackoverflow.com/questions/2124894/collectionviewsource-use-question) –  Jan 30 '15 at 07:08

2 Answers2

0

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 :)

blindmeis
  • 22,175
  • 7
  • 55
  • 74
  • Ah yes, MVVM is exactly what I'm trying to move to - sorry I didn't state it clearly in my question. I'll edit. – Sandra Jan 31 '15 at 02:12
  • You made me realize I may be able to bind to MyCol directly. I'll edit my question to include what I ended up doing. – Sandra Jan 31 '15 at 02:50
0

Make your collection MyCol as a collection of key and value, maybe something like,

new List<tuple<string,string>>()

Then bind your listBox to this collection with DisplayMemberPath as Item2 and use Item one as your key for searching etc.

Also you can use LINQ to sort your list,

myCol.OrderBy(p => p.Item2)
Muds
  • 4,006
  • 5
  • 31
  • 53
  • Thanks, though for me, changing away from SortedList is what I'm hoping to avoid, at least for this question. I edited my question to clarify the goal. – Sandra Jan 31 '15 at 02:48