【发布时间】:2011-09-18 01:10:28
【问题描述】:
我正在使用 WPF DataGrid,它将一组导入的文件呈现到程序中。 一切正常,但是当点击标题时我遇到了文件大小排序问题!
正常的排序方法无法区分 12*GB 和 12*MB,因此它们彼此相邻出现,这正是我不希望发生的情况。
知道如何解决这个问题吗?
→ 通过添加一个长列解决了这个问题,即使大小可能看起来 没意义我别无选择!
【问题讨论】:
标签: c# wpf sorting datagrid header
我正在使用 WPF DataGrid,它将一组导入的文件呈现到程序中。 一切正常,但是当点击标题时我遇到了文件大小排序问题!
正常的排序方法无法区分 12*GB 和 12*MB,因此它们彼此相邻出现,这正是我不希望发生的情况。
知道如何解决这个问题吗?
→ 通过添加一个长列解决了这个问题,即使大小可能看起来 没意义我别无选择!
【问题讨论】:
标签: c# wpf sorting datagrid header
我不认为在这种情况下正常的字符串排序会起作用。您必须实现自定义排序。
查看link,了解如何在 DataGrid 中实现自定义排序。它还提高了 DataGrid 中的排序性能。
您必须处理 DataGrid 的排序事件。
dataGrid.Sorting += new DataGridSortingEventHandler(SortHandler);
然后在事件处理程序中你会做这样的事情(取自here)
void SortHandler(object sender, DataGridSortingEventArgs e)
{
DataGridColumn column = e.Column;
IComparer comparer = null;
//i do some custom checking based on column to get the right comparer
//i have different comparers for different columns. I also handle the sort direction
//in my comparer
// prevent the built-in sort from sorting
e.Handled = true;
ListSortDirection direction = (column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
//set the sort order on the column
column.SortDirection = direction;
//use a ListCollectionView to do the sort.
ListCollectionView lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(this.ItemsSource);
//this is my custom sorter it just derives from IComparer and has a few properties
//you could just apply the comparer but i needed to do a few extra bits and pieces
comparer = new ResultSort(direction);
//apply the sort
lcv.CustomSort = comparer;
}
【讨论】:
首先,您需要一个IComparer<string>,它会根据后缀进行排序。我相信您可以自己编写,但这里有一种快速而简单的方法,只处理您列出的情况:
public class FileSizeComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var xFields = x.Split('*');
var yFields = y.Split('*');
if (xFields[1] == "GB" && yFields[0] == "MB") return 1;
if (xFields[1] == "MB" && yFields[0] == "GB") return -1;
return int.Parse(yFields[0]) - int.Parse(xFields[0]);
}
}
如果您要对数千行进行排序,这可以提高很多的效率。
然后你需要将你的比较器连接到DataGrid。以下 Stack Overflow 答案完美地解释了这一点:
您只需挂钩DataGrid.Sorting 事件并将比较器连接到您的列的ListCollectionView。
【讨论】:
您可能想尝试不同的方法:不要将数据格式化为字符串到网格中,然后面对字符串排序问题,而是将数据保留为数字并使用自定义列格式化例程来呈现大小MB、GB 等根据需要。
基本上,您需要从 IValueConverter 派生一个类并让它进行格式化(不用担心 'ConvertBack' 方法;它永远不会被调用)。
根据我的经验,将非字符串数据存储为字符串几乎总是错误的做法,正是出于这种原因。最好将其保留为任何类型的数据,并找到一种“在最后一刻”对其进行格式化的方法。
【讨论】: