WPF列表<t>排序

4

这是我在这里的第一篇文章。

我有一个列表"<"frameworkelement>,我正在使用选择过程填充它。每个frameworkelement都有一个uid,它保存其ZOrder。

我需要按照从低到高的ZOrder对它们进行排序。我可以使用listbox并像这样添加Uid来实现此目的:

            //Add Object Uid's
            ListBox lstTempOrder = new ListBox();
            foreach(FrameworkElement feObject in MainWindow.Data.SelectedObjects)
            {
                lstTempOrder.Items.Add(feObject.Uid);
            }
            //Reorder from 0 to above of the ZIndexes       
            lstTempOrder.Items.SortDescriptions.Add(new System.ComponentModel.SortDescription("", System.ComponentModel.ListSortDirection.Ascending));

但是我需要使用一个List"<"FrameWorkElement>和排序来完成这个任务。

以下是我填充List"<"T>的代码(SelectedObjects和CopyObjectsCollections都是List"<"FrameWorkElement>"列表)。

            foreach(FrameworkElement feObject in MainWindow.Data.SelectedObjects)
            {
                MainWindow.Data.CopyObjectsCollection.Add(feObject);
            }

我看了CollectionViewSource和IComparer,但我真的无法理解它们。


1
不要手动操作,你应该将ListBox绑定到CollectionViewSource,它允许对项目进行排序。请参阅绑定到集合获取示例。 - Clemens
谢谢你的回答。我不确定你所说的手动操作是什么意思。ListBox排序只是为了测试,它可以工作,但我无法弄清如何在List<T>“CopyObjectsCollection”上执行相同的操作。我以前从未使用过绑定。 - Drew
在WPF中,绑定是必不可少的。您可以开始阅读MSDN上的数据绑定概述文章。 - Clemens
谢谢关于绑定的信息。自从我开始使用WPF以来,我没有用到它。我只是想找到一种方法来像操作listbox一样对List<T>进行排序。我相信这可以在不使用绑定的情况下完成。无论如何,感谢您的回复。 - Drew
1个回答

4

我可能误读了您的问题,但如果您只想对List<T>进行排序,那么为什么不使用LinqOrderBy方法呢?

MainWindow.Data.CopyObjectsCollection = 
    MainWindow.Data.CopyObjectsCollection.OrderBy(f => f.Uid).ToList();

如果这个顺序对您的需求是错误的,那么您可以使用以下方式:
MainWindow.Data.CopyObjectsCollection = 
    MainWindow.Data.CopyObjectsCollection.OrderByDescending(f => f.Uid).ToList();

更新 >>>

OrderBy 是一个 LinQ 扩展方法。在你的类顶部添加 using System.Linq; 以使用它。 f 关联到您的 FrameworkElement 对象的一个实例。上述 lambda 表达式基本上意味着“使用 Uid 属性值进行排序”。

更新 2 >>>

OrderBy 方法不会改变原始集合……这就是为什么我的示例将集合设置为 OrderBy 方法的结果。请参见以下基本示例:

List<FrameworkElement> elements = new List<FrameworkElement>();
elements.Add(new FrameworkElement() { Uid = "Object1003-1" });
elements.Add(new FrameworkElement() { Uid = "Object1002-2" });
elements.Add(new FrameworkElement() { Uid = "Object1002-1" });
elements.Add(new FrameworkElement() { Uid = "Object1001-1" });
elements.Add(new FrameworkElement() { Uid = "Object1001-3" });
elements.Add(new FrameworkElement() { Uid = "Object1001-2" });
string result = string.Join(", ", elements.Select(f => f.Uid));
elements = elements.OrderBy(f => f.Uid).ToList();
string orderedResult = string.Join(", ", elements.Select(f => f.Uid));

通过比较resultorderedResult的值,您可以看到它们被完美排序。
更新3(也希望是最后一个)>>>
兄弟,您需要学习Lambda表达式...请查看MSDN上的Lambda表达式(C#编程指南)页面以获取更多信息。
elements = elements.OrderBy(f => f.Uid).ToList();

在这个Lambda表达式中,f在'=>'之前声明于此表达式中。通常使用类似Exceptions这样一个字母命名这些参数是很标准的,但我们也可以给它取任何名字。
elements = elements.OrderBy(frameworkElement => frameworkElement.Uid).ToList();

谢谢您的回复。看起来不错,但是我的List<Frameworkelement>似乎没有OrderBy方法。我猜“f”应该是我的“feObject”? - Drew
命名空间有所不同。我得到了一个“F”“feObject”的不能声明的错误,意思不同。我声明了一个新的FrameworkElement在这里使用,它编译通过了,但是foreach之后列表集合仍然保持不变。我尝试了foreach内部和之后的位置,我确定是我的问题,因为这看起来应该可以工作。谢谢你的帮助,我很感激。每个元素的Uid都像“Object1001-1”和“Object1002-2”等。 - Drew
如果我只是在foreach循环之后使用MainWindow.Data.CopyObjectsCollection.OrderBy(feObject => feObject.Uid).ToList();,这段代码可以编译通过。不确定为什么,因为我没有在其他地方声明feobject,但排序结果仍然保持不变,没有任何改变。 - Drew
“OrderBy”使用“feObject”在foreach循环中无法编译。 foreach(FrameworkElement feObject in MainWindow.Data.SelectedObjects) { MainWindow.Data.CopyObjectsCollection.Add(feObject); } - Drew
很难在这里写。我无法从foreach循环中解析出任何内容,以便在迭代后对集合进行操作。 - Drew
我将它翻译成了我的代码,最终让它工作了。由于您提供的信息不在我发布的代码行中,所以这更加困难,但我还是做到了。谢谢。 - Drew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接