1

I have a WPF app that has a combobox with lookup items. The combobox is populated with a ObservableCollection property that is created in my ViewModel.

The user can popup a window to type in a new lookup value. After the user enters a new value, I write the value to the lookup table in SQL Server. This part works well.

The problem is, I then want the combobox list to be updated and sorted correctly. What is the best way to do this?

If I do this, myLookupProperty.Add(newitem), my combobox is updated but it's not in the correct order.

If I do this, myLookupProperty = new ObservableCollection(Context.GetLookupTypes()), then the combobox is not updated until I click off the combobox and then back onto it.

Whats the best way to get newly inputted items into the table and have the combobox get these changes and have them sorted correctly?

Jerry
  • 6,357
  • 8
  • 35
  • 50

3 Answers3

2

A CollectionView with default sort description should work in your case. They work very well with ObservableCollection when Add \ Remove \ Update (ofcourse INotifyPropertyChanged based) takes place.

WPF-it
  • 19,625
  • 8
  • 55
  • 71
1

You can do

var sortedItems = myLookupProperty.Items.OrderBy(x => x.WhateverPropertyYouWantToSortOn);
myLookupProperty.Clear();
foreach (var item in sortedItems) {
  myLookupProperty.Add(item);
}

And that will work for you. The reason that the first method you tried didn't work (as I imagine you guessed) is that it just appends the new item to the bottom. The reason that the second method you proposed didn't work is that you break the binding when you replace the instance of ObservableCollection that your UI has bound to. It will not properly communicate that the contents are changed after this!

As a side note, it appears that this exact question was asked here!

Community
  • 1
  • 1
Kevek
  • 2,534
  • 5
  • 18
  • 29
  • Are use sure? Won't .Clear() like clear out all the items in myLookupProperty and there is nothing left to sort. – paparazzo Dec 23 '11 at 00:33
  • @BalamBalam that's the purpose of grabbing the items and storing them in the `sortedItems` variable (and sorting them during this process). That way you can re-insert them into the ObservableCollection. In my initial response I had typed this out too quickly and had reversed the order which is probably why you found it confusing, but I have corrected this! – Kevek Dec 23 '11 at 15:46
1

You can insert at a specific index.

    public void Insert ( int index, T item )

I suspect that on start up when you build from SQL the select statement has and order by so it gets built in the proper order.

You can also use a CollectionViewSource to sort but I think it would just be easier to insert at the proper index.

paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • This is re-implementing the wheel. To do this you basically have to implement insertion sort so that you can properly insert the new value into the proper index. Additionally, this would also mandate that wherever your initial range of values come from must be pre-sorted. – Kevek Dec 23 '11 at 15:48
  • @Kevek Insert one row at the proper position a LOT less overhead than copy, clear, and recreate the whole collection that you propose with the same amount of code. From the problem statement is clear the properties start sorted. As for reinventing the wheel a CollectionViewSource provides sorting in XAML or code behind (without the overhead of copy, clear, and recreate). – paparazzo Dec 23 '11 at 20:43
  • you're not wrong, but here's my only problem: If the OP didn't find the answer to this question which is provided in many other StackOverflow threads in their initial search for a solution, do you think they should be adding custom insertion sort code to do what you suggest? Your point about a CollectionViewSource is fine, and I would upvote that. – Kevek Dec 23 '11 at 22:31
  • Any solution is going to have custom code. I would go with the insert for any list over 100 simply for speed. Insert at the proper versus last position is a wash. Finding the insert point is going to be 1/2 the CPU and memory as a sort (on average the item will be 1/2 way down the list). And most likely the list is displayed read only several times for each update so the insert eliminates 1 or more sorts. I deal with ObservalbleCollection in excess of 20,000 and all the time and this is how I do it. I alway sort the to the most used display and then use CollectionViewSource addl. – paparazzo Dec 23 '11 at 23:12
  • P.S. if it is really large and has a lot of updates I will use a SortedDictionary. Lot of updates would be more than 1 update per 5 reads. – paparazzo Dec 23 '11 at 23:13