WPF DataGrid标头文件大小排序

本文关键字:文件大小 排序 DataGrid WPF | 更新日期: 2023-09-27 17:59:39

我正在使用一个WPF DataGrid,它将一组导入的文件呈现到程序中。一切都很好,但当标题被点击时,我遇到了排序文件大小的问题!

正常的排序方法无法区分12*GB12*MB,所以它们并排出现,这正是我不希望发生的情况。

知道如何解决这个问题吗?

→通过添加一个长列解决了问题,即使大小看起来可能很小毫无意义,我别无选择

WPF DataGrid标头文件大小排序

首先需要一个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答案完美地解释了这一点:

  • 如何将自定义排序规则应用于WPF数据网格

您只需挂接DataGrid.Sorting事件,并将比较器连接到列的ListCollectionView

我认为在这种情况下,正常的字符串排序不起作用。您必须实现自定义排序。

查看此链接以了解如何在DataGrid中实现自定义排序。它还提高了DataGrid中的排序性能。

您将不得不处理DataGrid的排序事件。

dataGrid.Sorting += new DataGridSortingEventHandler(SortHandler);

然后在事件处理程序中,你会做这样的事情(取自这里)

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;
}

您可能想尝试一种不同的方法:不要将数据格式化为字符串,然后面对字符串排序问题,而是将数据保留为数字,并根据需要使用自定义列格式化例程以MB、GB等呈现大小。

基本上,您需要从IValueConverter派生一个类,并让它进行格式化(不要担心"ConvertBack"方法;它永远不会被调用)。

根据我的经验,将非字符串数据存储为字符串几乎总是错误的,正是出于这种原因。无论它是什么类型的数据,最好都保留它,并在"最后一刻"找到格式化它的方法。