【问题标题】:Group, Sort, and then Merge to a Observable Collection?分组,排序,然后合并到一个可观察的集合?
【发布时间】:2015-10-15 06:14:26
【问题描述】:

我有一个具有“DisplayOrder”属性的项目列表。这可以具有 NULL 或 int 值。如果它具有 int 值,则它具有优先级,并且应该在 Observable Collection 的第一组中。第一组中的项目也按 DisplayOrder 排序。

如果为NULL,则属于第二组,按字母排序。

然后将第一组和第二组组合为我绑定到 ListView 的 Main Items Collection Observable Collection。

这是我当前的代码,但我担心是否有更优化的方法。

var MainItemCollection = new ObservableCollection<MainItemViewModel>();
var ItemsWithProperty = new ObservableCollection<MainItemViewModel>();
var ItemsWithNullProperty = new ObservableCollection<MainItemViewModel>();

foreach (var item in DataObject.MainItems)
{
    if (item.DisplayOrder == null)
        ItemsWithNullProperty.Add(new MainItemViewModel(item));
    else
        ItemsWithProperty.Add(new MainItemViewModel(item));
}

ItemsWithProperty = new ObservableCollection<MainItemViewModel>(ItemsWithProperty.OrderBy(c => c.DisplayOrder));
ItemsWithNullProperty = new ObservableCollection<MainItemViewModel>(ItemsWithNullProperty.OrderBy(c => c.Title));

//Add those with priorities first sorted by DisplayOrder 1,2,3,4
foreach (var c in ItemsWithProperty)
{
    MainItemCollection.Add(c);
}

//Add those without priority sorted Alphabetically
foreach (var c in ItemsWithNullProperty)
{
    MainItemCollection.Add(c);
}

谢谢!

【问题讨论】:

    标签: c# sorting observablecollection


    【解决方案1】:

    获取 DisplayOrder=null 的项目并按 Title 排序:

    ItemsWithNullProperty=DataObject.MainItems.Where(x=>x.DisplayOrder==null).OrderBy(o=>o.Title).ToList();
    

    使用 DisplayOrder 获取项目(除上述查询之外的所有项目)并按 DisplayOrder 排序:

    ItemsWithProperty= DataObject.MainItems.Except(ItemsWithNullProperty).OrderBy(o=>o.DisplayOrder).ToList();
    

    填写MainCollection中的数据:

    var allItems = MainItemCollection.Concat(ItemsWithProperty)
                                        .Concat(ItemsWithNullProperty)
                                        .ToList();
    

    【讨论】:

    • 感谢 TechieBee。我最终使用了自定义排序功能来优化性能。
    • @Water 太好了!!
    【解决方案2】:

    当做这样的事情时,您不需要所有那些中间的ObservableCollections - 您可以使用适当的数据结构,如数组、列表、字典、哈希集等或 Linq 查询。在这种特殊情况下,整个过程可以简化为这样

    var MainItemCollection = new ObservableCollection<MainItemViewModel>(DataObject.MainItems
        .OrderBy(item => item.DisplayOrder ?? int.MaxValue)
        .ThenBy(item => item.DisplayOrder == null ? item.Title : string.Empty)
    );
    

    【讨论】:

    • 谢谢伊万。我最终使用了自定义排序功能来优化性能。
    【解决方案3】:

    我觉得这是一个很常见的场景。 有一个已排序的 ObservableCollection 绑定到某些 XAML UI,一旦有更多数据可用,UI 就需要在不完全刷新的情况下更新。 每当像上面的建议一样创建新的 ObservableCollection 时,所有项目都将被反弹,因此 UI 会完全更新。

    我很惊讶没有库方法可以实现这一点。这是我想出的解决方案。希望有人会觉得它有用。

    public static class ObservableCollectionExtensions
    {
        public static void MergeSortedListIntoSortedObservableCollection<T>(this ObservableCollection<T> destination, IList<T> list, Func<T, T, int> compareFunc)
        {
            int dest_index = 0;
            int list_index = 0;
    
            while (list_index < list.Count)
            {
                if (dest_index >= destination.Count)
                {
                    destination.Add(list[list_index]);
                    list_index++;
                    dest_index++;
                }
                else
                {
                    if (compareFunc(destination[dest_index], list[list_index]) > 0)
                    {
                        destination.Insert(dest_index, list[list_index]);
                        list_index++;
                        dest_index++;
                    }
                    else
                    {
                        dest_index++;
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      • 2013-05-21
      • 2013-05-21
      • 2010-12-29
      • 1970-01-01
      相关资源
      最近更新 更多