如何在Datagrid中禁用排序组顺序,但是对组内的列进行排序?

时间:2015-05-22 18:27:20

标签: c# wpf xaml datagrid

我设置了一个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,然后对每个组中的列进行排序。

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

要明确我没有询问如何禁用排序,只是如何对组内的列进行排序,而不是按名称重新排序组本身。

1 个答案:

答案 0 :(得分:0)

我怀疑在组保持相同顺序时有任何简单的数据排序设置,但是您可以定义自定义排序器并处理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只能采用&#34; A&#34;,&#34; B&#34;和&#34; C&#34;而且你所希望的团体订单就像你提到的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);
    }