【问题标题】:Sorting CollectionViewSource grouping by external dictionary按外部字典对 CollectionViewSource 分组进行排序
【发布时间】:2018-02-13 08:27:46
【问题描述】:

我在 CollectionViewSource 中有一些组件对象需要排序,这些对象都有自定义类型。分组是在类型上完成的,组件按它们的名称排序。我现在需要做的是对组件类型的分组进行排序但是我需要根据外部源对这些组件类型进行排序,所以对象看起来有点像这样:

public class ComponentType
{
    public Guid Identification
    {
        get;
    }
}

public class Component
{
    public string Name
    {
        get;
    }

    public ComponentType Type
    {
        get;
    }
}

集合视图是这样创建的:

this.ComponentCollection = new CollectionViewSource();
this.ComponentCollection.Source = this.Components;
this.ComponentCollection.GroupDescriptions.Clear();
this.ComponentCollection.GroupDescriptions.Add(new PropertyGroupDescription("ComponentType"));
this.ComponentCollection.SortDescriptions.Clear();
this.ComponentCollection.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
this.ComponentCollection.Filter += this.FilterComponent;
this.ComponentCollection.View.Refresh();
RaisePropertyChanged(() => this.ComponentCollection);

我在创建 CollectionViewSource 的同一个类中也有以下字典,如下所示:

public Dictionary<Guid, int> ComponentTypePositions

其中key是组件类型的标识,int是应该先出现的类型的位置。

不能将位置作为属性放在 ComponentType 或 Component 类中,它需要是一个单独的列表。

如何根据 ComponentTypePositions 字典中对应的编号对分组进行排序?

【问题讨论】:

    标签: c# sorting collectionviewsource


    【解决方案1】:

    您需要基于包含您的位置编号的 Component 类创建一个新类型,并将其用于源列表的元素。这可以通过匿名类型内联完成:

    ComponentCollection = new CollectionViewSource();
    ComponentCollection.Source = (from c in Components
                                  select new
                                  {
                                      Name = c.Name,
                                      Type = c.Type,
                                      Pos = ComponentTypePositions[c.Type.Identification]
                                  }).ToList();
    ComponentCollection.GroupDescriptions.Clear();
    ComponentCollection.GroupDescriptions.Add(new PropertyGroupDescription("Type"));
    ComponentCollection.SortDescriptions.Clear();
    ComponentCollection.SortDescriptions.Add(new SortDescription("Pos", ListSortDirection.Ascending));
    ComponentCollection.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
    ComponentCollection.Filter += FilterComponent;
    ComponentCollection.View.Refresh();
    

    如果您的源列表需要可编辑,您可以使用自己的自定义列表类型:

    public class ComponentListElement
    {
        private Component comp;
    
        public ComponentListElement(Component comp, Dictionary<Guid, int> positionMap)
        {
            this.comp = comp;
            this.Pos = positionMap[comp.Type.Identification];
        }
    
        public string Name { get { return comp.Name; } }
        public ComponentType Type { get { return comp.Type; } }
        public int Pos { get; private set; }
    }
    
    public class ComponentList : Collection<ComponentListElement>
    {
        private Dictionary<Guid, int> positionMap;
    
        public ComponentList(Dictionary<Guid, int> positionMap)
        {
            this.positionMap = positionMap;
        }
    
        public void Add(Component item)
        {
            base.Add(new ComponentListElement(item, positionMap));
        }
    }
    

    并像这样使用它:

    ComponentList componentList = new ComponentList(ComponentTypePositions);
    foreach (var item in Components)
    {
        componentList.Add(item);
    }
    ComponentCollection.Source = componentList;
    

    【讨论】:

    • 这里不需要使用匿名类型,这只是一个示例。您还可以为元素和列表本身使用自定义类型。因此,列表然后处理新添加的项目需要字典中的位置的情况。我将编辑我的答案以使其清楚。
    猜你喜欢
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 2016-04-17
    • 2020-11-02
    • 1970-01-01
    相关资源
    最近更新 更多