在数据网格中设置自动生成的列的顺序在哪里合适?

Where is it appropriate to se the autogenerated columns' order in data grid?

我正在根据我的模型定义自动生成一堆列。我想更好地控制它们的显示顺序。从触发的事件开始这样做是否合适,如下所示?

private void OnAutoGeneratedColumns(Object sender, EventArgs eventArgs) { ... }

或者有没有办法为定义 class 的字段添加属性,以便我可以控制它们的显示顺序?我将数据网格绑定到我的视图模型中的列表集合视图,我在其中执行要显示的行和要隐藏的行的过滤。我应该改用它吗?

public ListCollectionView AllThingiesView { ... }

或者,自动生成列的开头可能是一种不合适的方法?我正在添加一些我自己的,在模型中实际上没有相应的 属性。

编辑

根据评论,我意识到问题可能得到了澄清。我得到了部分答案 - 使用 DisplayOrder。这就回答了如何做 的问题。然而,主要问题是where(或when)。关于 属性 的设置位置,我提出了一些建议,可能还有其他建议(更好的)。

另外,属性是什么好像不太清楚。我想知道是否有可能 control/specify 使用属性的列的索引(我的意思是 属性 上的 属性,而不是 属性本身。例如,以下伪代码显示了可能是一种可能的方法。

public class GridableThing
{
  [Index(3)]
  public String FirstProperty{ get; set; })
  [Index(1)]
  public String SecondProperty{ get; set; })
  [Index(2)]
  public String ThirdProperty{ get; set; })
}

在上面的例子中,如果没有另外设置,列将以第一-第二-第三的顺序出现。通过使用网格的 属性 DisplayIndex,我可以使用属性的 属性 对它们进行 3-1-2 排序。这种方法是否可行?

以我的愚见,AutoGeneratingColumns 事件处理程序不是插入管理列顺序的逻辑的正确位置。当所有列的自动生成完成时会发生此事件,因此当创建所有列时,您将插入一个用于混合它们的逻辑。可能最好直接以正确的顺序创建它们,而不是在一秒钟内重新排序。

此外,正如您所建议的,使用属性来设置列顺序会很棒(类似于 DisplayAttribute 的 Order 属性)。这样做,在我看来,意味着描述一个class,所以我对你的问题的回答是:把你的逻辑放在CustomTypeDescriptor中。好吧,也许你必须写更多的代码,你可以说这是解决问题的很长的路要走。也许我错了,但我更喜欢这种说 "this is the order of my columns (i.e. properties) of my class (or maybe my model)".

的方法

当然,为了 link 您的 class 到您的 CustomTypeDescriptor,您需要使用 TypeDescriptionProvider 属性:

[TypeDescriptionProvider(typeof(CustomTypeDescriptionProvider))]
public class Party : INotifyPropertyChanged
{
    /* ... */
}

并扩展 TypeDescriptionProvider class:

public class CustomTypeDescriptionProvider : TypeDescriptionProvider
{
    private static TypeDescriptionProvider defaultTypeProvider =
                TypeDescriptor.GetProvider(typeof(Party));

    public CustomTypeDescriptionProvider()
        : base(defaultTypeProvider)
    {
    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        ICustomTypeDescriptor defaultDescriptor =
                            base.GetTypeDescriptor(objectType, instance);

        return new CustomTypeDescriptor(defaultDescriptor, instance);
    }

    public ICustomTypeDescriptor GetBaseTypeDescriptor(Type objectType, object instance)
    {
        return base.GetTypeDescriptor(objectType, instance);
    }
}

最后一步是创建您的 CustomTypeDescriptor:

class CustomTypeDescriptor : System.ComponentModel.CustomTypeDescriptor
{
    private List<PropertyDescriptor> propertyDescriptors = new List<PropertyDescriptor>();
    private PropertyDescriptorCollection propertyDescriptorCollection;

    public CustomTypeDescriptor(ICustomTypeDescriptor parent, object instance)
        : base(parent)
    {
        CustomTypeDescriptionProvider customTypeDescriptionProvider = new WpfApplication1.CustomTypeDescriptionProvider();
        ICustomTypeDescriptor typeDescriptor = customTypeDescriptionProvider.GetBaseTypeDescriptor(typeof(Party), null);
        PropertyDescriptorCollection tempPropertyDescriptorCollection = typeDescriptor.GetProperties();
        propertyDescriptors.Add(tempPropertyDescriptorCollection[2]);
        propertyDescriptors.Add(tempPropertyDescriptorCollection[1]);
        propertyDescriptors.Add(tempPropertyDescriptorCollection[0]);
        /* put here your ordering logic */

        propertyDescriptorCollection = new PropertyDescriptorCollection(propertyDescriptors.ToArray());
    }

    public override PropertyDescriptorCollection GetProperties()
    {
        return propertyDescriptorCollection;
    }

    public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        return propertyDescriptorCollection;
    }
}

这里我使用默认的 TypeDescriptor 来检索 Party 对象的 PropertyDescriptors。然后我按照我喜欢的方式对它们进行排序(最终我可以读取属性以确定正确的顺序)。

很高兴听到对我的想法的一些反馈。