【问题标题】:Chaning processing sequence of ObservableCollection<T> (c#)更改 ObservableCollection<T> (c#) 的处理顺序
【发布时间】:2017-03-20 06:35:01
【问题描述】:

有没有一种简单的方法可以影响 c# 中 ObservableCollection 的处理顺序?

假设我有以下课程:

public class GeneratorObject : IComparable
{
        int processingSequence {get; set;}
        string property1 {get; set;}
        Boolean property2 {get; set;}

        public GeneratorObject(int processingSequence)
        {
            this.processingSequence = processingSequence;
        }

        public int CompareTo(object obj)
        {
             // Implementation
        }               
}

处理序列可以是每个自然数。

我想迭代其中的一些

ObservableCollection<GeneratorObject> toIterate = new ObservableCollection<GeneratorObject>();

toIterate.Add(new GeneratorObject(99));
toIterate.Add(new GeneratorObject(1));
toIterate.Add(new GeneratorObject(10));
toIterate.Add(new GeneratorObject(6));

foreach (GeneratorObject field in toIterate)
{
    // Manipulating the properties of field
}

我真的不想对集合进行排序,尤其是在视图中。我只想更改迭代的顺序。首先是序列号最小的元素,..., 此外,重要的是要说,我在迭代时操纵项目,不能只使用集合的副本。

我已经实现了 IComparable 并认为我可以轻松地说例如Collection.Sort() 不会破坏与 UI 的绑定。

感谢您的帮助。

【问题讨论】:

  • 你试过什么?痛苦的显而易见的答案是对集合的副本进行排序(最终 - 由下面发布的一个答案推荐)。你有什么理由不这样做?请更具体,并提供一个很好的minimal reproducible example,清楚地显示您尝试过的内容,解释您遇到的具体问题。
  • 感谢您的建议。下次我会尝试更具体。不应对的问题是,我在迭代时操纵项目。
  • 请编辑您的问题以提供说明。请注意,即使您进行了澄清,问题仍然很广泛。也就是说,虽然您可以在底层集合中维护一个排序的索引数组,但如果您在迭代时更改集合,您可能应该在每次想要对最低序列执行操作时对集合进行线性扫描#,找到最低的#。
  • 另一种选择是向GeneratorObject 添加一个属性,以保持显示顺序,并使集合保持顺序# 顺序。然后使用WPF内置的CollectionViewSource按显示顺序属性#排序显示。
  • 能否请您澄清一下您的索引排序数组和基础集合的方式?

标签: c# sorting observablecollection icomparable


【解决方案1】:

您可以创建列表的copy,对其进行排序然后迭代copy列表:

        //ObservableCollection<GeneratorObject> toIterate;
        // I am assuming that 'toIterate' is not null and bound to the UI
        toIterate.Add(new GeneratorObject(99));
        toIterate.Add(new GeneratorObject(1));
        toIterate.Add(new GeneratorObject(10));
        toIterate.Add(new GeneratorObject(6));

        var copy = toIterate.ToList();
        copy.Sort();

        foreach (GeneratorObject field in copy)
        {

        }

此处的排序操作在不同的列表上执行,因此不会更改 UI 中的顺序。

【讨论】:

  • 感谢您的回答。问题是,我在迭代时操纵对象。我也有这个想法要复制,但后来我失去了对真实对象的引用。
【解决方案2】:

如果您在迭代时列表正在更改,那么您可以循环直到列表为空,然后在每次迭代时找到最小值,而不是迭代。

while (toIterate.Any())
{
    GeneratorObject generatorObject = toIterate.Min();
    // do something with it
}

【讨论】:

    【解决方案3】:

    感谢副本的提示。我不知道这是否是一个好的答案(尤其是关于性能),但我通过以下方式解决了这个问题。

    var copy = toIterate.ToList();
    copy.Sort();
    
    // iterate through the sorted List
    foreach (GeneratorObject field in copy)
    {
        // get the original object regarding to this sorted item
        GeneratorObject originalObjectForAction = getGeneratorObject(toIterate, field);
        // do stuff with the original item
    }
    
    public GeneratorObject getGeneratorObject(ObservableCollection<GeneratorObject> list, GeneratorObject objekt)
    {
        foreach (DwhRoboterGeneratorObjekt field in list)
        {
            if (field == objekt) return field;
        }
        throw new Exception("Not found");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-07
      • 2014-11-29
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多