在数据网格中设置自动生成的列的顺序在哪里合适?
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。然后我按照我喜欢的方式对它们进行排序(最终我可以读取属性以确定正确的顺序)。
很高兴听到对我的想法的一些反馈。
我正在根据我的模型定义自动生成一堆列。我想更好地控制它们的显示顺序。从触发的事件开始这样做是否合适,如下所示?
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。然后我按照我喜欢的方式对它们进行排序(最终我可以读取属性以确定正确的顺序)。
很高兴听到对我的想法的一些反馈。