I used kat's processed DataGrid to create Behavior for the WPF DataGrid.
The behavior saves the initial SortDescriptions and applies them every time the ItemsSource changes. You can also provide an IEnumerable<SortDescription> that will call the resort with every change.
Behavior
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); } } } } } } }
XAML with optional SortDescriptions parameter
<DataGrid ItemsSource="{Binding View}" > <i:Interaction.Behaviors> <commons:DataGridSortBehavior SortDescriptions="{Binding SortDescriptions}"/> </i:Interaction.Behaviors> </DataGrid>
ViewModel Configuring ICollectionView
View = CollectionViewSource.GetDefaultView(_collection); View.SortDescriptions.Add(new SortDescription("Sequence", ListSortDirection.Ascending));
Optional: ViewModel property to provide mutable SortDescriptions
public IEnumerable<SortDescription> SortDescriptions { get { return new List<SortDescription> {new SortDescription("Sequence", ListSortDirection.Ascending)}; } }
Juergen
source share