【问题标题】:How to customize names in "Add" button dropdown in the PropertyGrid custom collection editor如何在 PropertyGrid 自定义集合编辑器的“添加”按钮下拉列表中自定义名称
【发布时间】:2016-04-03 12:18:11
【问题描述】:

我正在使用 PropertyGrid 来编辑集合。带有集合的对象定义如下:

class ObjWithCollection
{
    [Editor(typeof(MyCustomCollectionEditor),typeof(UITypeEditor))]
    public List<ItemBase> collection { get; set; } = new List<ItemBase>();//ItemBase is abstract
}

该集合包含两种类型的对象,派生自 ItemBase 类:Item1Item2。这些类定义如下:

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) };
    }
}

然后我将我的自定义编辑器绑定到具有 Editor 属性的 ObjWithCollection.collection 属性(请参阅 ObjWithCollection.collection 定义)。

这很好用,我可以编辑我的收藏,包括添加新项目。添加按钮有一个下拉菜单,允许用户选择要添加的元素类型。 editor window http://i.share.pho.to/31d50d09_o.png

但在“添加”按钮下拉菜单中,名为“Item1”和“Item2”的项目我无法更改这些名称。我尝试了 DisplayName 属性,ToString 覆盖,但没有运气。

所以,问题是我如何为添加按钮菜单的元素输出自定义名称。

【问题讨论】:

    标签: c# editor propertygrid


    【解决方案1】:

    我认为这不可能直接来自属性网格的代码。但是,您可以使用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)) };
        }
    

    现在,您应该会在菜单中看到显示名称而不是名称。

    【讨论】:

      【解决方案2】:

      您还可以通过连接到 CollectionForm 的控件来更改文本(丑陋,不推荐,不要在生产中使用,请注意它可以随时更改和过时)

       public sealed class OutputItemEditor : CollectionEditor // need a reference to System.Design.dll
      {
          public OutputItemEditor(Type type)
              : base(type)
          {
          }
      
          protected override Type[] CreateNewItemTypes()
          {
              return new[] { typeof(StaticOutputItem), typeof(VariableOutputItem),typeof(ExpressionOutputItem) };
          }
      
          protected override CollectionForm CreateCollectionForm()
          {
              CollectionForm collectionForm = base.CreateCollectionForm();            
              collectionForm.Text = "Output Collection";
      
              //Modify the Add Item Button Text
              try
              {
                  //You can use "collectionForm.Controls.Find("addButton",true)" here also
                  foreach (ToolStripItem item in collectionForm.Controls[0].Controls[1].Controls[0].ContextMenuStrip.Items)
                  {
                      //Since Item Names are the Type Names
                      switch (item.Text)
                      {
                          case "StaticOutputItem":
                              item.Text = "Static Output Item";
                              break;
                          case "VariableOutputItem":
                              item.Text = "Variable Output Item";
                              break;
                          case "ExpressionOutputItem":
                              item.Text = "Expression Output Item";
                              break;
                          default:
                              break;
                      }
                  }
              }
              catch (Exception)
              {
              }
      
              return collectionForm;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多