【发布时间】:2015-03-27 09:41:28
【问题描述】:
我试图让 DataGrid 中的一行始终位于顶部,同时仍然能够按列(int 和 string 列)对所有其他行进行排序。
我的数据结构提供了一点帮助:第一列名为“Id”,而我试图保持在顶部的行始终具有所有 Id 中最低的 Id。此行包含聚合值。
典型的 DataGrid 可能如下所示:
ID | Name | Result1 | Result2
5 | avg | 2 | 5
6 | opt1 | 1 | 3
7 | opt2 | 3 | 7
可能有 n 列,列数会在运行时发生变化。 DataGrid 绑定到 ListCollectionView,我还实现了基于 trilson86's answer 的自定义排序器:
<DataGrid result:CustomSortBehaviour.AllowCustomSort="True"
IsReadOnly="True"
ItemsSource="{Binding ResultDataView}">
</DataGrid>
到目前为止,使用 trilson86 的解决方案,我在排序时设法将第一行保持在顶部。这是我的 CustomSortBehavior 类中的处理程序,它为自定义排序器准备有用的数据块(例如当前 DataGrid 中的最小 ID):
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;
var min = listColView.Cast<DataRowView>().Min(x => x.Row[0]);
var sorter = new MyComparer();
e.Handled = true;
var direction = (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
e.Column.SortDirection = sorter.SortDirection = direction;
sorter.IdOfFirstRow = Convert.ToInt32(min);
listColView.CustomSort = sorter;
}
自定义排序器本身:
public int Compare(object x, object y)
{
var rowView1 = x as DataRowView;
var rowView2 = y as DataRowView;
var row1 = rowView1.Row;
var row2 = rowView2.Row;
var row1Id = Convert.ToInt32(row1[0]);
var row2Id = Convert.ToInt32(row2[0]);
if (row1IdValue == IdOfFirstRow)
return -1;
if (row2IdValue == IdOfFirstRow)
return 1;
if (SortDirection == ListSortDirection.Ascending) {
return row2Id.CompareTo(row1Id);
}
else
{
return row1Id.CompareTo(row2Id);
}
}
这只是解决方案的一半。按原样硬编码,我只能按 ID 排序。因为列将在运行时添加,所以我无法在设计时定义所有列并根据列值类型(int 或 string)附加排序器。
如何在保持具有最小 Id 的行保持在顶部的限制的同时按所有其他列排序?
【问题讨论】:
-
为什么需要将第一行固定在顶部?我假设它 not 显示标题信息,但我无法想象什么样的 data 需要留在顶部。
-
我有一个数据表,其中标题下方的第一行显示汇总信息,而所有其他行不显示。因此,无论何时排序,都要求包含汇总信息的第一行应位于标题的正下方。
-
我不会将聚合信息存储在表本身中,而是存储在单独的视图模型中(如果需要,该模型可以在表的 ExtendedProperties 中)。然后为 DataGrid 创建一个自定义模板,您可以在其中添加标题和实际行之间的聚合信息。
-
这是一个好主意,因为它可以让我的专有“模型”保持清洁。但是,我现在正在尝试使用自定义排序功能。如果结果不可用,我可能会尝试你的想法 [然后会奖励你赏金]