如果项目是文件路径,则对与文件名对应的列表框进行排序

本文关键字:列表 排序 文件名 项目 文件 路径 如果 | 更新日期: 2023-09-27 18:35:43

我有一个包含ListBoxItem s的ListBox,如果实际路径太长,Content是完整文件路径或裁剪路径的字符串(文件路径的开头被裁剪,例如"C:''MyFolder1''MyFolder2''MyFile.df" -> "...1''MyFolder2''MyFile.df")。项的Tag是自定义对象,其中包含完整的文件路径、文件名以及裁剪的文件路径(如有必要):

internal class MyClass
{
    internal string filePath, filePathCropped, fileName;
    internal ListBoxItem listBoxItem;
    //the paths are set somewhere here, whenever a file is opened and then an event is
    //raised that adds them to the ListBox. filePathCropped is equal to filePath, if
    //the path is short enough.
}
public partial class MainWindow : Window
{
    internal void AddFileToList(object sender, EventArgs e)
    {
        MyClass myClass = sender as MyClass ;
        myClass.listBoxItem = new ListBoxItem
        {
            Content = myClass.filePathCropped,
            Tag = myClass
        };
        listBoxOpenFiles.Items.Add(myClass.listBoxItem);
        SortFileList();
    }
    private void SortFileList()
    {
        //I would like to sort my list here according to fileName
    }
}

不幸的是,我不太确定排序机制是如何工作的。SO 上有几个主题,但它们主要涉及根据列表中的实际字符串进行排序,但这并不是我在这里想要实现的目标。

我试过这个:

private void SortFileList()
{
    listBoxOpenFiles.Items.SortDescriptions.Add(
        new System.ComponentModel.SortDescription((Tag as MyClass).fileName, 
        System.ComponentModel.ListSortDirection.Ascending));
}

但这引起了NullRefenceException,因为Tag没有设定。我不完全确定,如何访问我的项目的TagProperty,或者如何不根据整个内容字符串进行排序,而只根据最后一位(当然也等于文件名)进行排序。

如果项目是文件路径,则对与文件名对应的列表框进行排序

首先,确保你实际使用的是属性,而不是变量:

internal class MyClass
{
    internal string filePath, filePathCropped;
    internal ListBoxItem listBoxItem;
    internal string FileName {get;set;}
}

其次,您应该指定应用排序的属性:

listBoxOpenFiles.Items.SortDescriptions.Add(
        new SortDescription("Tag.FileName", ListSortDirection.Ascending));

也就是说,你的代码已经变得非常混乱:你实际上应该只使用 XAML 来处理这个问题。此外,您不需要调用Sort方法。确保基础集合使用的是 ObservableCollection ,它将得到处理。

经过对不同方向的更多研究,我在这里找到了一个相当简单的解决方案,我以前没有想过它不使用集合,而是使用"老式"方式。

private void SortFileList()
{
    int length = listBoxOpenFiles.Items.Count;
    string[] keys = new string[length];
    ListBoxItem[] items = new ListBoxItem[length];
    for(int i = 0; i < length; ++i)
    {
        keys[i] = ((listBoxOpenFiles.Items[i] as ListBoxItem).Tag as MyClass).FileName;
        items[i] = listBoxOpenFiles.Items[i] as ListBoxItem;
    }
    Array.Sort(keys, items);
    listBoxOpenFiles.Items.Clear();
    for (int i = 0; i < length; ++i)
    {
        listBoxOpenFiles.Items.Add(items[i]);
    }
}

考虑到它是一个 WPF 程序,这可能不是最优雅的解决方案,但它无需更改前面代码中的任何内容即可工作。