wpf 按多列对 C# 列表进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15576282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:15:19  来源:igfitidea点击:

Sorting a C# List by multiple columns

c#wpflistsortingcombobox

提问by isakavis

I have a question on sorting a list by multiple columns. In the following sample, even though I sorted to show None, A First Description, B Second..., the list still prints in the order it was inserted.

我有一个关于按多列对列表进行排序的问题。在下面的示例中,即使我排序为 show None, A First Description, B Second...,列表仍按插入顺序打印。

List<MySample> samples = new List<MySample>();

samples.Add(new MySample { SortOrder = 1, Data = "A First Description", Description = "A First Description" });
samples.Add(new MySample { SortOrder = 1, Data = "C Third Description", Description = "C Third Description" });
samples.Add(new MySample { SortOrder = 1, Data = "B Second Description", Description = "B Second Description" });
samples.Add(new MySample { SortOrder = 0, Data = "None", Description = "None" });
samples.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();

foreach (var item in samples)
{
    Console.WriteLine(item);
}

public class MySample
{
    public int SortOrder { get; set; }
    public string Description { get; set; }
    public object Data { get; set; }
}

If I change my code to do the following, then it prints in the desired order.

如果我更改代码以执行以下操作,则它会按所需顺序打印。

samples = samples.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();

Can the ordering be done without assigning(like above)?

可以在不分配的情况下完成订购吗(如上)?

FYI, this example is not actual code. I need to databind this list to a ComboBoxin WPFthrough code behind using FrameworkElementFactory.

仅供参考,此示例不是实际代码。我需要数据绑定该列表到ComboBoxWPF通过后面的代码使用FrameworkElementFactory

Thanks for your help!

谢谢你的帮助!

Update with my approach:

用我的方法更新:

var collectionView = CollectionViewSource.GetDefaultView(<My list to be sorted>);
collectionView.SortDescriptions.Add(new SortDescription("SortOrder", ListSortDirection.Ascending));
collectionView.SortDescriptions.Add(new SortDescription("Description", ListSortDirection.Ascending));

The above did the trick in the UI. I thank all for the fast answers.

以上在 UI 中起到了作用。我感谢所有人的快速答复。

回答by musefan

The reason is because OrderBydoes not transform the object it is called on, instead it returns a new result. You should use it like this:

原因是因为OrderBy它不会转换它被调用的对象,而是返回一个新的结果。你应该像这样使用它:

samples = samples.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();

This is the way the OrderByfunction works. Why would you need it to work the other way, especially for just a few extra characters.

这就是OrderBy函数的工作方式。为什么你需要它以另一种方式工作,尤其是对于几个额外的字符。

You couldmake it work, by creating your own extension methods that do the same thing except work on the reference to the object rather than creating a new result, but this is not worth the trouble at all.

可以通过创建自己的扩展方法来使其工作,除了处理对对象的引用而不是创建新结果之外,这些方法可以做同样的事情,但这根本不值得麻烦。



If you need something though, you could just wrap the LINQ in an extension method like so:

如果你需要一些东西,你可以将 LINQ 包装在一个扩展方法中,如下所示:

public static void MyOrderBy(this List<MySample> list)
{
    list = list.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();
}

and the use it like so:

并像这样使用它:

samples.MyOrderBy();

It's just an idea though, I don't know if it will work, or if it's a good idea or not.

这只是一个想法,我不知道它是否会奏效,或者它是否是一个好主意。

回答by Joe Enos

Since you have a List, you can do it the old school way:

既然你有一个List,你可以用老派的方式来做:

samples.Sort((s1, s2) => {
    int compare = s1.SortOrder.CompareTo(s2.SortOrder);
    if (compare != 0) return compare;
    compare = s1.Description.CompareTo(s2.Description);
    return compare;
});

But I'd probably stick with LINQ. Much easier to read.

但我可能会坚持使用 LINQ。更容易阅读。

回答by Tim S.

You could change your example to:

您可以将示例更改为:

//other code above...
samples.Add(new MySample { SortOrder = 0, Data = "None", Description = "None" });
foreach (var item in samples.OrderBy(a => a.SortOrder).ThenBy(a => a.Description))
//other code below...

Note that samplesis unchanged by the ordering - only the order for that particular loop-through is set.

请注意,samples排序不会改变 - 仅设置了该特定循环的顺序。

If neither of these are acceptable, please explain your need in more detail.

如果这些都不可接受,请更详细地说明您的需求。

回答by JerKimball

Just for an alternative, "please don't do this unless nothing else fits" route, you couldadd a new property to sort on an amalgamation:

只是为了替代,“除非没有其他合适的东西,否则请不要这样做”路线,您可以添加一个新属性来对合并进行排序:

class NoReallyThisIsACodeSmell
{
    public string SortPlusDescription
    {
           return string.Concat(SortOrder, Description);
    }
}