考虑这个代码(为了示例的目的,通用的类型名称):
// Bound to ListBox.ItemsSource _items = new ObservableCollection- (); // ...Items are added here ... // Specify custom IComparer for this collection view _itemsView = CollectionViewSource.GetDefaultView(_items) ((ListCollectionView)_itemsView).CustomSort = new ItemComparer();
当我设置时CustomSort
,集合按照我的预期排序.
但是,我要求数据在运行时重新排序,以响应属性的更改Item
.将Item
类从派生INotifyPropertyChanged
和我知道的财产火灾正确地为我的数据模板更新屏幕上的价值,只有排序逻辑不被调用.
我还尝试提高INotifyPropertyChanged.PropertyChanged
传递空字符串,以查看通用通知是否会导致启动排序.没有香蕉.
编辑为了回应Kent的建议,我想我会指出使用它对项目进行排序具有相同的结果,即集合排序一次但不会随着数据的变化而重新排序:
_itemsView.SortDescriptions.Add( new SortDescription("PropertyName", ListSortDirection.Ascending));
Drew Noakes.. 8
我发现WPF博士的这篇文章首先回答了我的问题,然后继续讨论调用对性能的影响Refresh
.一些关键摘录:
不幸的是,Refresh()方法导致视图的完全重新生成.当视图中出现Refresh()时,它会引发CollectionChanged通知并将Action提供为"Reset".ListBox的ItemContainerGenerator接收此通知,并通过丢弃项目的所有现有视觉效果进行响应.然后它完全重新生成新的项目容器和视觉效果.
然后他描述了一种改善性能的hacky解决方法.而不是调用刷新,删除,更改然后重新添加项目.
我原以为列表视图可以跟踪一个更改的项目,并知道在视图中单独重新定位该项目.
一种新的方法介绍在.NET 3.5 SP1涉及的接口IEditableObject
是通过数据绑定到模板提供事务编辑,方法BeginEdit()
,CancelEdit()
和EndEdit()
.阅读文章了解更多信息.
编辑正如用户346528指出的那样,IEditableObject
3.5SP1实际上并不是新的.它实际上看起来就像1.0以来一直在框架中.
我发现WPF博士的这篇文章首先回答了我的问题,然后继续讨论调用对性能的影响Refresh
.一些关键摘录:
不幸的是,Refresh()方法导致视图的完全重新生成.当视图中出现Refresh()时,它会引发CollectionChanged通知并将Action提供为"Reset".ListBox的ItemContainerGenerator接收此通知,并通过丢弃项目的所有现有视觉效果进行响应.然后它完全重新生成新的项目容器和视觉效果.
然后他描述了一种改善性能的hacky解决方法.而不是调用刷新,删除,更改然后重新添加项目.
我原以为列表视图可以跟踪一个更改的项目,并知道在视图中单独重新定位该项目.
一种新的方法介绍在.NET 3.5 SP1涉及的接口IEditableObject
是通过数据绑定到模板提供事务编辑,方法BeginEdit()
,CancelEdit()
和EndEdit()
.阅读文章了解更多信息.
编辑正如用户346528指出的那样,IEditableObject
3.5SP1实际上并不是新的.它实际上看起来就像1.0以来一直在框架中.
由于接受的答案指示我,我能够强制单项重新定位代码
IEditableCollectionView collectionView = DataGrid.Items; collectionView.EditItem(changedItem); collectionView.CommitEdit();
哪里changedItem
是视图模型(中项目ItemsSource
集合).
这样你就不需要你的项目来实现任何类似的接口IEditableObject
(在我看来,在某些情况下,这些接口非常复杂且难以实现).