如何处理Observable类的集合

时间:2016-05-31 09:23:09

标签: c# linq sorting observablecollection

我有以下TracefieldPartProgramClass

public class TracefieldPartProgramClass
{
    public TracefieldPartProgramClass() { }
    public ObservableCollection<Tuple<string, object, object>> obcTraceFieldPartProgram = new ObservableCollection<Tuple<string, object, object>>();
}

我用它来制作以下集合:

ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass>();

现在填写之后我希望能够按照我想要的方式进行排序(比如Tracefield [0])。 所以我实现了这个:

private ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass> SortOnTracefield(ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass> obcToSort)
{
var obcSorted = new ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass>();
obcSorted = obcToSort.OrderBy(w => w.obcTraceFieldPartProgram[0].Item3.ToString());<--- this is where I get the error
return obcSorted;

}

但是当我这样做时,我收到了这个错误:

  

错误CS0266无法将类型'System.Linq.IOrderedEnumerable'隐式转换为'System.Collections.ObjectModel.ObservableCollection'。存在显式转换(您是否错过了演员?)

3 个答案:

答案 0 :(得分:3)

试试这个:

private ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass> SortOnTracefield(ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass> obcToSort)
{
    var sorted = obcToSort.OrderBy(w => w.obcTraceFieldPartProgram[0].Item3.ToString();
    return new ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass>(sorted);
}

您可以将IEnumerable传递给observable集合的构造函数。

但是,它返回集合的新实例。因此,如果未排序的实例绑定到GUI,则可能无法更新GUI。另一个支持排序的方法是使用ICollectionView

SO问题how-do-i-sort-an-observable-collection也可能适合您。以下扩展方法可用于在不重新创建的情况下对ObservableCollection进行排序:

static class Extensions
{
    public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable
    {
        List<T> sorted = collection.OrderBy(x => x).ToList();
        for (int i = 0; i < sorted.Count(); i++)
            collection.Move(collection.IndexOf(sorted[i]), i);
    }
}

但是,您的TracefieldPartProgramClass课程需要实施IComparable,否则您需要实施自定义IComparer<TracefieldPartProgramClass>并将其传递给排序方法。

答案 1 :(得分:2)

Enumerable.OrderBy不会返回ObservableCollection而是IEnumerable<T>,您可以使用List<T> constructor创建新内容:

var obcSortedList = obcToSort
    .OrderBy(w => w.obcTraceFieldPartProgram[0].Item3.ToString())
    .ToList();  
var obcSorted = new ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass>(obcSortedList);

答案 2 :(得分:2)

如错误所示,您尝试将IOrderedEnumerable分配给ObservableCollection类型的变量,这是不可能的。

但幸运的是,ObservableCollection有一个constructor,需要IEnumerable并使用IEnumerable的项目预填充。{/ 1>

因此,为了使该错误消失,请使用:

var sortedEnumerable = obcToSort.OrderBy(w => w.obcTraceFieldPartProgram[0].Item3.ToString());
obcSorted = new ObservableCollection<EasyRunBinSerializableData.TracefieldPartProgramClass>(sortedEnumerable );