我有 C#\WPF 应用程序,它只是在列表框控件中显示变量名称及其值的列表。当用户点击“刷新”按钮时,将使用变量的新值重新创建列表。有些变量可能已经改变,而有些变量保持不变。
我希望自上次刷新以来已更改的值位于列表框的顶部,但想不出一种优雅的方式来解决这个问题。任何想法或示例将不胜感激。
谢谢!
最好为您的列表项(模型)提供一些额外的功能,这些功能旨在简单地为视图提供服务,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
并且ListOfModels
是ObservableCollection
,这就是自动完成排序所需的全部内容。
与其拥有名称/值对的对象列表,不如将其视为具有 // 属性的对象Name
列表。当您更新对象列表时,您可以进行适当的设置,并将其用作排序的一部分。Value
IsChanged
IsChanged
IsChanged
特别是,不要将其视为对字符串列表进行排序。您有一个变量列表,这些变量具有属性 ( name
, value
, isChanged
)。你的列表框绑定到一个CollectionView
(Listbox.Items
给你的那个,或者你从中得到的东西CollectionViewSource
)。上面CollectionView
有SortDescriptions
,您可以将其设置为先排序IsChanged
,然后再排序Name
。
可能还有更多选择:
Except
查看差异。Except
使用顶部的结果和下面的其余顺序创建新列表。Timestamp
,这将标记项目的创建时间。选择一个间隔,多旧的项目应该在顶部。读取新值,并将满足条件的值(间隔中的最新值)放在顶部。或者你可以按那个对它们进行排序TimeStamp
。使用类似的东西:
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);
我没有测试过代码,这个想法应该会变得清晰。
我喜欢 Jeff 的想法,但每次用户更新列表时,它都需要额外的逻辑来重置 IsChanged 值。尝试将时间戳添加到您的名称/值对,并在每次更新值时更新时间戳。然后只需将时间戳添加到您的排序中。