我使用来自 kat 的 interited DataGrid 为 WPF DataGrid 创建一个行为。
该行为保存初始的 SortDescriptions 并将它们应用于ItemsSource
. 您还可以提供一个IEnumerable<SortDescription>
在每次更改时都会引起响应的选项。
行为
public class DataGridSortBehavior : Behavior<DataGrid>
{
public static readonly DependencyProperty SortDescriptionsProperty = DependencyProperty.Register(
"SortDescriptions",
typeof (IEnumerable<SortDescription>),
typeof (DataGridSortBehavior),
new FrameworkPropertyMetadata(null, SortDescriptionsPropertyChanged));
/// <summary>
/// Storage for initial SortDescriptions
/// </summary>
private IEnumerable<SortDescription> _internalSortDescriptions;
/// <summary>
/// Property for providing a Binding to Custom SortDescriptions
/// </summary>
public IEnumerable<SortDescription> SortDescriptions
{
get { return (IEnumerable<SortDescription>) GetValue(SortDescriptionsProperty); }
set { SetValue(SortDescriptionsProperty, value); }
}
protected override void OnAttached()
{
var dpd = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof (DataGrid));
if (dpd != null)
{
dpd.AddValueChanged(AssociatedObject, OnItemsSourceChanged);
}
}
protected override void OnDetaching()
{
var dpd = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof (DataGrid));
if (dpd != null)
{
dpd.RemoveValueChanged(AssociatedObject, OnItemsSourceChanged);
}
}
private static void SortDescriptionsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGridSortBehavior)
{
((DataGridSortBehavior) d).OnItemsSourceChanged(d, EventArgs.Empty);
}
}
public void OnItemsSourceChanged(object sender, EventArgs eventArgs)
{
// save description only on first call, SortDescriptions are always empty after ItemsSourceChanged
if (_internalSortDescriptions == null)
{
// save initial sort descriptions
var cv = (AssociatedObject.ItemsSource as ICollectionView);
if (cv != null)
{
_internalSortDescriptions = cv.SortDescriptions.ToList();
}
}
else
{
// do not resort first time - DataGrid works as expected this time
var sort = SortDescriptions ?? _internalSortDescriptions;
if (sort != null)
{
sort = sort.ToList();
var collectionView = AssociatedObject.ItemsSource as ICollectionView;
if (collectionView != null)
{
using (collectionView.DeferRefresh())
{
collectionView.SortDescriptions.Clear();
foreach (var sorter in sort)
{
collectionView.SortDescriptions.Add(sorter);
}
}
}
}
}
}
}
带有可选 SortDescriptions 参数的 XAML
<DataGrid ItemsSource="{Binding View}" >
<i:Interaction.Behaviors>
<commons:DataGridSortBehavior SortDescriptions="{Binding SortDescriptions}"/>
</i:Interaction.Behaviors>
</DataGrid>
ViewModel ICollectionView 设置
View = CollectionViewSource.GetDefaultView(_collection);
View.SortDescriptions.Add(new SortDescription("Sequence", ListSortDirection.Ascending));
可选:ViewModel 属性,用于提供可变的 SortDescriptions
public IEnumerable<SortDescription> SortDescriptions
{
get
{
return new List<SortDescription> {new SortDescription("Sequence", ListSortDirection.Ascending)};
}
}