按外部字典对 CollectionViewSource 分组进行排序

Sorting CollectionViewSource grouping by external dictionary

我在 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 class 中,它需要是一个单独的列表。

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

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

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;