如何在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.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);
}