2016-04-03 235 views
1

我正在使用PropertyGrid來編輯集合。與收集的對象被定義爲以下:如何在PropertyGrid自定義集合編輯器中的「添加」按鈕下拉列表中自定義名稱

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

該集合包含兩種類型,從衍生的對象ItemBase類:項目1項目2。定義如下這些類:

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

然後,我結合我的自定義編輯器將ObjWithCollection.collection財產與編輯 attibute(見ObjWithCollection.collection定義)。

這工作正常,我能夠編輯我的集合,包括添加新項目。 Add按鈕有一個下拉菜單,允許用戶選擇要添加的元素的類型。 editor window http://i.share.pho.to/31d50d09_o.png

但在添加按鈕下拉列表稱爲「項目1」和「項目2」的項目,我不能改變這個名字。我試過DisplayName屬性,ToString重寫,但沒有運氣。

所以,的qustion是如何,我可以輸出爲的元素自定義名稱添加按鈕菜單。

回答

2

我不認爲這是可以直接從屬性網格的代碼。但是,您可以使用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)) }; 
    } 

現在,你應該看到的,而不是在名稱中顯示名稱菜單。

0

您還可以通過掛接到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; 
    } 
} 
相關問題