如果Items是文件路径,则根据文件名对ListBox进行排序

时间:2014-12-29 12:07:19

标签: c# wpf sorting listbox

我有一个包含ListBox的{​​{1}},如果实际路径太长(文件路径的开头),则ListBoxItem是完整文件路径或裁剪路径的字符串被裁剪,例如“C:\ MyFolder1 \ MyFolder2 \ MyFile.df” - >“... 1 \ MyFolder2 \ MyFile.df”)。这些项的Content是自定义对象,包含完整的文件路径,文件名以及必要时裁剪的文件路径:

Tag

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

我试过了:

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

但由于private void SortFileList() { listBoxOpenFiles.Items.SortDescriptions.Add( new System.ComponentModel.SortDescription((Tag as MyClass).fileName, System.ComponentModel.ListSortDirection.Ascending)); } 未设置,因此会引发NullRefenceException。我不完全确定,如何访问我的项目的Tag或如何不根据整个内容字符串排序,而只是最后一位(当然也等于文件名)。< / p>

2 个答案:

答案 0 :(得分:0)

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

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,并将对其进行处理。

答案 1 :(得分:0)

经过一番不同方向的研究后,我找到了一个相当简单的解决方案here,在没有使用集合之前我还没想过,而是#34}老式的&#34;办法。

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程序,这可能不是最优雅的解决方案,但它可以在不必更改前面代码中的任何内容的情况下工作。