我有一个关于按多列排序列表的问题。在下面的示例中,即使我排序为显示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; }
}
如果我更改我的代码以执行以下操作,则会按所需顺序打印。
samples = samples.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();
订购是否可以在不分配的情况下完成(如上所述)?
仅供参考,此示例不是实际代码。我需要通过使用ComboBox
后面的代码将此列表数据绑定到WPF
中的FrameworkElementFactory
。
感谢您的帮助!
以我的方法更新:
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));
以上在UI中发挥了作用。我感谢大家的快速回答。
答案 0 :(得分:4)
原因是因为OrderBy
不会转换它所调用的对象,而是返回一个新结果。你应该像这样使用它:
samples = samples.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();
这是OrderBy
函数的工作方式。为什么你需要它以另一种方式工作,特别是对于一些额外的角色。
你可以使其工作,通过创建自己的扩展方法来做同样的事情,除了处理对象的引用而不是创建新的结果,但这不值得麻烦所有。
如果你需要一些东西,你可以用这样的扩展方法包装LINQ:
public static void MyOrderBy(this List<MySample> list)
{
list = list.OrderBy(a => a.SortOrder).ThenBy(a => a.Description).ToList();
}
并使用它如此:
samples.MyOrderBy();
这只是一个想法,但我不知道它是否有用,或者它是否是个好主意。
答案 1 :(得分:2)
由于你有一个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;
});
但我可能会坚持使用LINQ。更容易阅读。
答案 2 :(得分:1)
您可以将示例更改为:
//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...
请注意,samples
未按顺序更改 - 仅设置该特定循环的顺序。
如果这些都不可接受,请更详细地解释您的需求。
答案 3 :(得分:0)
只是为了另一种选择,“请不要这样做,除非没有其他条件适合”路线,你可以添加一个新属性来对合并进行排序:
class NoReallyThisIsACodeSmell
{
public string SortPlusDescription
{
return string.Concat(SortOrder, Description);
}
}