最简单的方法是将集合包装在 CollectionViewSource 中。
首先,您需要确保集合项实现INotifyPropertyChanged 和PropertyChanged 事件,只要SortOrder 属性更改就会引发。然后像这样定义集合视图源:
<CollectionViewSource x:Key="CollectionView" Source="{Binding Collection}" IsLiveSortingRequested="True">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="SortOrder" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
其中xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase",并将其放入DataGrid 的祖先控件的资源字典中(例如Window.Resources 或UserControl.Resources)。最后将定义的集合视图源设置为DataGrid的项目源:
<DataGrid ItemsSource="{Binding Source={StaticResource CollectionView}}">
...
</DataGrid>
现在,无论何时更改任何项目上的 SortOrder 属性,UI 都应相应更新。
更新
如果项目没有实现INotifyPropertyChanged,上述解决方案将不起作用。您可能需要考虑创建一个包装类,该类将公开必要的属性并实现INotifyPropertyChanged(这种设计模式通常称为“装饰器模式”)。但是,如果它不是一个选项,您可以在视图模型上定义集合视图并将其绑定到集合本身,并在对项目进行任何更改时手动刷新视图。以下是它的外观示例:
public IEnumerable<Item> Collection
{
get { ... }
set
{
//store the value in the backing field
if (value != null)
{
CollectionView = CollectionViewSource.GetDefaultView(value);
CollectionView.SortDescriptions.Add(new SortDescription
{
Direction = ListSortDirection.Ascending,
PropertyName = "SortOrder",
});
}
else
CollectionView = null;
}
}
public ICollectionView CollectionView
{
get { ... }
set
{
//store the value in the backing field and raise PropertyChanged
}
}
在 XAML 中,绑定到集合视图:
<DataGrid ItemsSource="{Binding CollectionView}">
...
</DataGrid>
然后,每当您对项目进行更改时,请在完成后致电CollectionView.Refresh(),UI 将会更新。