1

I've got C#\WPF app that simply displays a list of variable names and their values in a listbox control. When the user hits a Refresh button, the list is recreated with the new values for the variables. Some of the variables may have changed, while some have stayed the same.

I would like for the values that have changed since the last refresh to be at the top of the listbox, but can't think of an elegant way to go about this. Any ideas or examples would be appreciated.

Thank you!

Dbloom
  • 1,302
  • 3
  • 18
  • 45
  • store the current values with javascript, compare to the new values. if different, put them on top of the stack. if not, put them on the bottom. – Joe T Jan 31 '13 at 22:50
  • what does your data structure look like? – Daniel A. White Jan 31 '13 at 22:54
  • Joe why would he want to store the values with javascript when he could do `List.Sort()` for example.. ? not a good suggestion btw – MethodMan Jan 31 '13 at 22:56
  • I'm running this inside of an SCCM/MDT Task Sequence, so I am using the TSEnvClass to grab variable objects and put them into an observable collection. I'm then simply adding all of the elements from the collection into the listbox. – Dbloom Jan 31 '13 at 22:58

5 Answers5

2

It would be best if gave your list items (models) some additional functionality that is intended to simply service the view, viewmodel-style -- and of course you can wrap your models inside viewmodels if you want to keep them pure.

For example, you can give your models a Changed property that you can set (or, the Value property setter can change it automatically whenever the value changes). This property can then be used to sort the items in the ListBox by sorting the collection view that the box is bound to:

<CollectionViewSource x:Key="SortedModels" Source="{Binding ListOfModels}">
    <CollectionViewSource.SortDescriptions>
        <SortDescription PropertyName="Changed"/>
    </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

<ListBox ItemsSource="{Binding Source={StaticResource SortedModels}}"/>

Assuming that your models implement INotifyPropertyChanged and ListOfModels is an ObservableCollection, that's all it will take to have sorting done automatically.

Jon
  • 428,835
  • 81
  • 738
  • 806
1

Instead of having a list of objects that are name/value pairs, think of it as a list of objects that have Name / Value / IsChanged properties. When you update the list of objects, you can set IsChanged appropriately, and just use IsChanged as part of your sort.

In particular, don't think of this as sorting a list of strings. You've got a list of variables, which have properties (name, value, isChanged). Your listbox is binding to a CollectionView (either the one that Listbox.Items gives you, or something you got from CollectionViewSource). That CollectionView has SortDescriptions on it, which you can set so as to sort by IsChanged first, then by Name.

mipe34
  • 5,596
  • 3
  • 26
  • 38
Jeff Paulsen
  • 2,132
  • 1
  • 12
  • 10
1

There are probably more options:

  1. Keep the state of current list. Load new list. Use linq Except to see differences. Create new list with the result from Except on the top and the rest order below.
  2. Extend your item with some Timestamp, that will mark, when the item was created. Choose an interval, how old items should be on top. Read new values, and those that satisfies the condition (the newest one in the interval) put on the top. Or you can just sort them by that TimeStamp.
mipe34
  • 5,596
  • 3
  • 26
  • 38
1

Use something like:

var olditems = new Hashset<string>(listbox.items); // or List<T>
List<string> newitems = getNewItems();
newitems = newitems.RemoveAll(x => olditems.Contains(x));
listbox.Items.Clear();
listbox.Items.Add(newitems);
listbox.Items.Add(olditems);

I have not tested the code, bit the idea should become clear.

See also: Using LINQ to remove elements from a List<T>

Community
  • 1
  • 1
DasKrümelmonster
  • 5,816
  • 1
  • 24
  • 45
0

I like Jeff's Idea but it requires extra logic to reset the IsChanged value every time the user updates the list. Try adding a time stamp to your name/ value pair and updating the time stamp every time the value is updated. Then just add the time stamp to your sort.

BenCamps
  • 1,694
  • 15
  • 25