1

我有 C#\WPF 应用程序,它只是在列表框控件中显示变量名称及其值的列表。当用户点击“刷新”按钮时,将使用变量的新值重新创建列表。有些变量可能已经改变,而有些变量保持不变。

我希望自上次刷新以来已更改的值位于列表框的顶部,但想不出一种优雅的方式来解决这个问题。任何想法或示例将不胜感激。

谢谢!

4

5 回答 5

2

最好为您的列表项(模型)提供一些额外的功能,这些功能旨在简单地为视图提供服务,viewmodel 样式——当然,如果您想让它们保持纯净,您可以将模型包装在 viewmodel 中。

例如,您可以为模型提供一个Changed可以设置的属性(或者,Value属性设置器可以在值更改时自动更改它)。然后,此属性可用于ListBox通过对框绑定到的集合视图进行排序来对 中的项目进行排序:

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

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

假设您的模型实现INotifyPropertyChanged并且ListOfModelsObservableCollection,这就是自动完成排序所需的全部内容。

于 2013-01-31T22:56:42.100 回答
1

与其拥有名称/值对的对象列表,不如将其视为具有 // 属性的对象Name列表。当您更新对象列表时,您可以进行适当的设置,并将其用作排序的一部分。ValueIsChangedIsChangedIsChanged

特别是,不要将其视为对字符串列表进行排序。您有一个变量列表,这些变量具有属性 ( name, value, isChanged)。你的列表框绑定到一个CollectionViewListbox.Items给你的那个,或者你从中得到的东西CollectionViewSource)。上面CollectionViewSortDescriptions,您可以将其设置为先排序IsChanged,然后再排序Name

于 2013-01-31T22:54:20.150 回答
1

可能还有更多选择:

  1. 保持当前列表的状态。加载新列表。使用 linqExcept查看差异。Except使用顶部的结果和下面的其余顺序创建新列表。
  2. 使用 some 扩展您的项目Timestamp,这将标记项目的创建时间。选择一个间隔,多旧的项目应该在顶部。读取新值,并将满足条件的值(间隔中的最新值)放在顶部。或者你可以按那个对它们进行排序TimeStamp
于 2013-01-31T22:58:25.657 回答
1

使用类似的东西:

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

我没有测试过代码,这个想法应该会变得清晰。

另请参阅:使用 LINQ 从 List<T> 中删除元素

于 2013-01-31T22:59:55.827 回答
0

我喜欢 Jeff 的想法,但每次用户更新列表时,它都需要额外的逻辑来重置 IsChanged 值。尝试将时间戳添加到您的名称/值对,并在每次更新值时更新时间戳。然后只需将时间戳添加到您的排序中。

于 2013-01-31T23:03:08.763 回答