2016-04-03 28 views
1

'daki "Ekle" düğmesi açılır menüsünde adlar nasıl özelleştirilir Bir koleksiyonu düzenlemek için PropertyGrid özelliğini kullanın.PropertyGrid özel koleksiyon editörü

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

toplama elde edilen iki tip nesneler içeren sınıf ItemBase: toplama bir amacı, aşağıdaki gibi tanımlanmıştır Item1 ve Öğe2'yi. Aşağıdaki olarak tanımlanan Bu sınıflar:

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") { } 
} 

editörü aracılığıyla koleksiyonuna yeni öğeler eklemek edebilmek için, ben de özel koleksiyonu düzenleyicisi sınıfı tanımlanmış ve toplanması için uygun her türlü listelemek için CreateNewItemTypes geçersiz:

class MyCustomCollectionEditor : CollectionEditor 
{ 
    public MyCustomCollectionEditor(Type type) : base(type){} 
    protected override Type[] CreateNewItemTypes() 
    { 
     return new Type[] { typeof(Item1), typeof(Item2) }; 
    } 
} 

Sonra (bkz Editör attibute ile ObjWithCollection.collection özelliğine benim özel editörü bağlayan ObjWithCollection.collection tanım).

Bu, iyi çalışıyor ve yeni öğelerin eklenmesi de dahil olmak üzere koleksiyonumu düzenleyebiliyorum. Ekle düğmesinin, kullanıcının eklenecek öğe türünü seçmesine izin veren bir açılan menüsü vardır. editor window http://i.share.pho.to/31d50d09_o.png

Ama Ekle düğmesine içinde "Öğe1" ve "Item2" adı verilen öğeleri açılır menüsünü ve bu isimleri değiştirilemez. DisplayName özniteliğini, ToString geçersiz kılmayı denedim, ancak şans yok.

Yani, qustion Ben çıkış unsurları için özel isimler düğme menüsü ekleme yapabilirsiniz nasıl olduğunu.

cevap

2

Bunun doğrudan özellik kılavuzunun kodundan mümkün olduğunu düşünmüyorum. Ancak, sistemi kandırmak için TypeDelegator'u kullanabilir ve örneğin, varsayılan olarak kullandığı türün Ad özelliğinin yerine, örneğin DisplayName özniteliğini kullanmak üzere zorlayabilirsiniz.

1) Bu gibi özel bir TypeDelegator oluşturun:

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) böyle) (CreateNewItemTypes değiştirin:

protected override Type[] CreateNewItemTypes() 
    { 
     return new Type[] { new MyTypeDelegator(typeof(Item1)), new MyTypeDelegator(typeof(Item2)) }; 
    } 

Şimdi, bunun yerine adına ekran isimlerini görmelisiniz Menü.

0

Ayrıca CollectionForm en Kontroller içine çengel metni değiştirebilirsiniz (Çirkin Değil Tavsiye değiştirilemez olabilir unutmayın ve zaman içinde eskimiş, üretimde KULLANMAYIN)

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