WPF DataGrid CustomSort for each Column

trilson86

I have a WPF DataGrid bound to a CollectionViewSource that encapsulates an ObservableCollection. This CollectionViewSource has two main objectives:

1) To group each item by a specific property of T. I'm using a ValueConverter in the GroupDescription to get the grouping behaviour I want.

2) To sort the grid by a) primarily the group name (as defined above) and b) the individual group items. I'm achieving this by attaching a custom IComparer to the CollectionViewSource's 'CustomSort' property.

This works great for the most part, however as soon as a column header is clicked, the sorting logic is overridden. I don't want to disable sorting, however I was wondering if it was possible to assign a custom sorting order for a specific column?

To make things a bit clearer, suppose a user clicks 'ColumnA' - at the moment, the sorting logic encapsulated by my CustomSorter is overridden and the DataGrid is now sorted by that property. Rather than sorting by the selected property, I'd like to instead reverse the logic of the CustomSorter.

trilson86

I created a couple of attached properties which handle this issue. I hope this comes in handy for someone!

First - a simple interface for your directionalised comparer. This extends IComparer but gives us one more property (SortDirection). Your implementation should use this to determine the correct ordering of elements (which would otherwise have been lost).

public interface ICustomSorter : IComparer
{
    ListSortDirection SortDirection { get; set; }
}

Next is the attached behavior - this does two things: 1) tells the grid to use custom sort logic (AllowCustomSort=true) and b) gives us the ability to set this logic at a per-column level.

public class CustomSortBehaviour
{
    public static readonly DependencyProperty CustomSorterProperty =
        DependencyProperty.RegisterAttached("CustomSorter", typeof(ICustomSorter), typeof(CustomSortBehaviour));

    public static ICustomSorter GetCustomSorter(DataGridColumn gridColumn)
    {
        return (ICustomSorter)gridColumn.GetValue(CustomSorterProperty);
    }

    public static void SetCustomSorter(DataGridColumn gridColumn, ICustomSorter value)
    {
        gridColumn.SetValue(CustomSorterProperty, value);
    }

    public static readonly DependencyProperty AllowCustomSortProperty =
        DependencyProperty.RegisterAttached("AllowCustomSort", typeof(bool),
        typeof(CustomSortBehaviour), new UIPropertyMetadata(false, OnAllowCustomSortChanged));

    public static bool GetAllowCustomSort(DataGrid grid)
    {
        return (bool)grid.GetValue(AllowCustomSortProperty);
    }

    public static void SetAllowCustomSort(DataGrid grid, bool value)
    {
        grid.SetValue(AllowCustomSortProperty, value);
    }

    private static void OnAllowCustomSortChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var existing = d as DataGrid;
        if (existing == null) return;

        var oldAllow = (bool)e.OldValue;
        var newAllow = (bool)e.NewValue;

        if (!oldAllow && newAllow)
        {
            existing.Sorting += HandleCustomSorting;
        }
        else
        {
            existing.Sorting -= HandleCustomSorting;
        }
    }

    private static void HandleCustomSorting(object sender, DataGridSortingEventArgs e)
    {
        var dataGrid = sender as DataGrid;
        if (dataGrid == null || !GetAllowCustomSort(dataGrid)) return;

        var listColView = dataGrid.ItemsSource as ListCollectionView;
        if (listColView == null)
            throw new Exception("The DataGrid's ItemsSource property must be of type, ListCollectionView");

        // Sanity check
        var sorter = GetCustomSorter(e.Column);
        if (sorter == null) return;

        // The guts.
        e.Handled = true;

        var direction = (e.Column.SortDirection != ListSortDirection.Ascending)
                            ? ListSortDirection.Ascending
                            : ListSortDirection.Descending;

        e.Column.SortDirection = sorter.SortDirection = direction;
        listColView.CustomSort = sorter;
    }
}

To use it, implement an ICustomComparer (with a parameterless constructor) and in your XAML:

<UserControl.Resources>
    <converters:MyComparer x:Key="MyComparer"/>
    <!-- add more if you need them -->
</UserControl.Resources>
<DataGrid behaviours:CustomSortBehaviour.AllowCustomSort="True" ItemsSource="{Binding MyListCollectionView}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Test" Binding="{Binding MyValue}" behaviours:CustomSortBehaviour.CustomSorter="{StaticResource MyComparer}" />
    </DataGrid.Columns>
</DataGrid>

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

각 열에 대한 WPF DataGrid CustomSort

분류에서Dev

WPF: Programatically adding a ContextMenu to a DataGrid column header

분류에서Dev

Why are DataTable values not showing on WPF DataGrid when column name contains '/'?

분류에서Dev

Why are DataTable values not showing on WPF DataGrid when column name contains '/'?

분류에서Dev

Create a DataGrid in WPF with column type equal with DataGridViewButtonColumn of WinForm

분류에서Dev

WPF datagrid binding with datatable

분류에서Dev

UserControls의 wpf DataGrid

분류에서Dev

WPF DataGrid 계산

분류에서Dev

blink a wpf datagrid row

분류에서Dev

WPF DataGrid의 Colspan

분류에서Dev

WPF DataGrid 배경

분류에서Dev

WPF DataGrid SelectItem BeforeRightClick

분류에서Dev

WPF TreeView ListBox DataGrid

분류에서Dev

WPF DataGrid XML Binding and 1 Column for status that changes every 5 seconds

분류에서Dev

Update dynamic column in datagrid

분류에서Dev

WPF DataGrid 용 ScrollIntoView (MVVM)

분류에서Dev

WPF DataGrid update on CollectionChanged fails

분류에서Dev

Memory leak issue in WPF datagrid

분류에서Dev

wpf Datagrid 셀 서식

분류에서Dev

wpf Datagrid 셀 서식

분류에서Dev

WPF how to ensure uniqueness in DataGrid

분류에서Dev

WPF Datagrid C #의 ComboBox

분류에서Dev

ScrollViewer 내부의 WPF DataGrid

분류에서Dev

WPF DataGrid, 셀의 값 변환

분류에서Dev

WPF C # DataGrid 편집 셀

분류에서Dev

RecognizesAccessKey가 해제 된 WPF DataGrid

분류에서Dev

RecognizesAccessKey가 해제 된 WPF DataGrid

분류에서Dev

VS2010 WPF DataGrid Sorts Improperly

분류에서Dev

WPF C# DataGrid edit cell