WPF的DataGrid CustomSort为每列 [英] WPF DataGrid CustomSort for each Column

查看:389
本文介绍了WPF的DataGrid CustomSort为每列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF的DataGrid绑定到CollectionViewSource它封装一个ObservableCollection。这CollectionViewSource有两个主要目标:

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

1)组中的每个项目由T.我使用的是ValueConverter在GroupDesc​​ription来得到我想要的分组行为的特定属性。

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)排序网格由一个)主要组名(如上所定义)和b)各组的项目。我通过将一个自定义的IComparer到CollectionViewSource的CustomSort'属性实现这一点。

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?

为了让事情更清楚一点,假设一个用户点击ColumnA - 的那一刻,我的CustomSorter封装的排序逻辑被覆盖,并在DataGrid,现在是由物业来分类。而不是由选定的属性排序,我想,而不是扭转CustomSorter的逻辑。

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.

推荐答案

我创建了几个附加属性,它处理这个​​问题。我希望这是在方便的人!

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

第一 - 为您directionalised比较器的简单接口。这延伸的IComparer,但让我们多了一个属性(SortDirection)。你的实现应该使用这种以确定正确的元素排序(否则将被丢失)。

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; }
}

接下来是附加的行为 - 这做了两件事:1)告诉电网使用自定义排序逻辑(AllowCustomSort = TRUE)和b)让我们在每列级设置这个逻辑的能力。

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

    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(DataGrid), 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;
    }
}

要使用它,实现一个ICustomComparer(带参数的构造函数),并在你的XAML:

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>

这篇关于WPF的DataGrid CustomSort为每列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆