我正在使用 PropertyGrid 编辑集合。具有集合的对象定义如下:
class ObjWithCollection
{
[Editor(typeof(MyCustomCollectionEditor),typeof(UITypeEditor))]
public List<ItemBase> collection { get; set; } = new List<ItemBase>();//ItemBase is abstract
}
该集合包含两种类型的对象,派生自 ItemBase 类:Item1 和 Item2。这些类定义如下:
public abstract class ItemBase
{
public string Name { get; set; }
public ItemBase() { }
public ItemBase(string name) { Name = name; }
}
public class Item1:ItemBase
{
public Item1():base("Item 1 name"){}
}
[DisplayName("item2 test display name")]
public class Item2:ItemBase
{
public Item2() : base("item 2 name") { }
}
为了能够通过编辑器向集合添加新项目,我还定义了自定义集合编辑器类并重写 CreateNewItemTypes 以列出所有适合集合的类型:
class MyCustomCollectionEditor : CollectionEditor
{
public MyCustomCollectionEditor(Type type) : base(type){}
protected override Type[] CreateNewItemTypes()
{
return new Type[] { typeof(Item1), typeof(Item2) };
}
}
然后,我将自定义编辑器绑定(bind)到具有 Editor 属性的 ObjWithCollection.collection 属性(请参阅 ObjWithCollection.collection 定义)。
这工作正常,我可以编辑我的收藏,包括添加新项目。添加按钮有一个下拉菜单,允许用户选择要添加的元素类型。 editor window http://i.share.pho.to/31d50d09_o.png
但是在“添加”按钮下拉列表中,名为“Item1”和“Item2”的项目,我无法更改此名称。我尝试了 DisplayName 属性、ToString 覆盖,但没有成功。
所以,问题是如何输出添加按钮菜单元素的自定义名称。
最佳答案
我认为这不可能直接从属性网格的代码中实现。但是,您可以使用 TypeDelegator欺骗系统并强制它使用您的 DisplayName 属性来代替默认使用的类型的 Name 属性。
1) 创建一个自定义 TypeDelegator,如下所示:
class MyTypeDelegator : TypeDelegator
{
public MyTypeDelegator(Type delegatingType)
: base(delegatingType)
{
}
public override string Name
{
get
{
var dna = (DisplayNameAttribute)typeImpl.GetCustomAttribute(typeof(DisplayNameAttribute));
return dna != null ? dna.DisplayName : typeImpl.Name;
}
}
}
2)像这样修改CreateNewItemTypes():
protected override Type[] CreateNewItemTypes()
{
return new Type[] { new MyTypeDelegator(typeof(Item1)), new MyTypeDelegator(typeof(Item2)) };
}
现在,您应该看到显示名称而不是菜单中的名称。
关于c# - 如何在 PropertyGrid 自定义集合编辑器中自定义 "Add"按钮下拉列表中的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36385305/