如何在Datagrid中禁用排序组顺序,但保留组内列的排序

本文关键字:排序 保留 顺序 Datagrid | 更新日期: 2023-09-27 17:50:24

我设置了一个DataGrid,并将其绑定到一个添加了组的ICollectionView

myView.Add(new PropertyGroupDescription("MyProp"));

然后添加了一个简单的组样式:

                <DataGrid.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel>
                                    <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Padding="3"/>
                                </StackPanel>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                        <GroupStyle.ContainerStyle>
                            <Style TargetType="{x:Type GroupItem}">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type GroupItem}">
                                            <Expander IsExpanded="True">
                                                <Expander.Header>
                                                    <StackPanel Orientation="Horizontal">
                                                        <TextBlock Text="{Binding Path=Name}" />
                                                        <TextBlock Text="{Binding Path=ItemCount}" Margin="8,0,4,0"/>
                                                        <TextBlock Text="Element(s)"/>
                                                    </StackPanel>
                                                </Expander.Header>
                                                <ItemsPresenter />
                                            </Expander>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </GroupStyle.ContainerStyle>
                    </GroupStyle>
                </DataGrid.GroupStyle>

无论如何,组本身最初是按我希望的顺序排列的。然而,当用户单击DataGrid中的标题按该列排序时,它不仅会对列进行排序,还会按名称的顺序对组进行排序。因此,如果我的组按顺序是B、A、C,它们将被排序为A、B、C,然后每组中的列被排序。

有没有一个简单的设置可以让列排序只对列进行排序,而不对组顺序进行排序。

需要明确的是,我并不是在问如何禁用排序,而是在不按名称重新排序组本身的情况下,如何对组内的列进行排序。

如何在Datagrid中禁用排序组顺序,但保留组内列的排序

当组保持相同顺序时,我怀疑是否有任何简单的设置可以对数据进行排序,但您可以定义自定义排序器并处理DataGrid.Sorting事件,以根据所需顺序对数据进行分类。

假设Category是分组所基于的属性,我们有这样的东西:

MyList.Add(new ItemViewModel { ID = 1, Amount = 5, Category = "A" , ...});
// add some more items
GroupedList = new ListCollectionView(MyList);
GroupedList.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

然后,您需要编写一个自定义排序器,根据您想要的组顺序对数据进行排序,作为主要排序参数(以保持组顺序不变(,然后根据用户选择的列对数据进行分类,作为次要参数(以对每个组内的数据进行排序(。

注意,我写这篇文章时假设Category只能取"A"、"B"answers"C",而且你想要的组顺序是B-A-C,就像你提到的那样

public class CustomSorter : IComparer
{
    public ListSortDirection? Direction { get; set; }
    public string SortMember { get; set; }
    public CustomSorter(string sortMember, ListSortDirection? direction)
    {
        SortMember = sortMember;
        Direction = direction;
    }
    // A custom comparer based on group header ("Category" in this example) 
    // in "B"<"A"<"C" order.
    public int Compare(object x, object y)
    {
        var xVm = (ItemViewModel)x;
        var yVm = (ItemViewModel)y;
        if (xVm.Category == yVm.Category)
            return CompareBySortMember(xVm,yVm);
        if (xVm.Category == "B")
            return -1;
        if (xVm.Category == "A" && yVm.Category == "C")
            return -1;
        return 1;
    }
    // When two items have the same Category, comparison is made based on 
    // "SortMemberPath" property of the sorting column.
    private int CompareBySortMember(ItemViewModel xVm, ItemViewModel yVm)
    {
        var xValue = xVm.GetType().GetProperty(SortMember).GetValue(xVm);
        var yValue = yVm.GetType().GetProperty(SortMember).GetValue(yVm);
        int result = xValue.ToString().CompareTo(yValue.ToString());
        return Direction == ListSortDirection.Ascending ? result * -1 : result;
    }
}

最后:

    private void DataGrid_Sorting(object sender, DataGridSortingEventArgs e)
    {
        e.Handled = true;
        // Set the sort order on the column
        e.Column.SortDirection = (e.Column.SortDirection != ListSortDirection.Ascending) 
            ? ListSortDirection.Ascending : ListSortDirection.Descending;
        // Sort data based on predefined order of group headers and currently sorting column.
        GroupedList.CustomSort = new CustomSorter(e.Column.SortMemberPath, e.Column.SortDirection);
    }