最近遇到一個項目須要使用的propertyGrid來讓用戶自定義屬性,在遇到對集合進行操做的的時候遇到幾個問題:編輯器
1.在集合編輯器上,屬性設計區域下面的沒有屬性描述區域,致使有的用戶沒法知道這個屬性有啥用,以下圖ide
2.集合編輯器只能指定同一個類型,但有個需求是須要在一個集合裏添加基於同一個基類的不一樣拓展的多個類型函數
3.須要限制集合編輯器Items的數量,不能超過指定數量.測試
先處理第一個問題,老規矩,遇到問題的時候先google下,結果沒找到我須要的,只能老老實實去看看源碼但願能有點收貨,運氣還好,反編譯了下CollectionEditor,發現其實google
是有描述區域的,只是不知道微軟咋想的,默認是不顯示的,可是能夠經過反射使其顯示,具體代碼直接貼上spa
1 public class ExtendCollectionEditor : CollectionEditor 2 { 3 public ExtendCollectionEditor(Type type) : base(type) 4 { 5 } 6 protected override CollectionForm CreateCollectionForm() 7 { 8 CollectionForm frm = base.CreateCollectionForm(); 9 FieldInfo fileinfo = frm.GetType().GetField("propertyBrowser", BindingFlags.NonPublic | BindingFlags.Instance); 10 if (fileinfo != null) 11 { 12 (fileinfo.GetValue(frm) as System.Windows.Forms.PropertyGrid).HelpVisible = true; 13 } 14 frm.Width = 700; 15 frm.Height = 600; 16 return frm; 17 } 18 }
下面是效果設計
第二個問題也是經過源碼+測試搞定,直接上代碼code
1 /// <summary> 2 /// 實現多個已知對象的集合添加 3 /// </summary> 4 public class ItemCollectionEditor : ExtendCollectionEditor 5 { 6 #region MyRegion 7 public ItemCollectionEditor(Type type) : base(type) 8 { 9 } 10 11 12 protected override Type[] CreateNewItemTypes() 13 { 14 return new Type[] 15 { 16 typeof(Panel), 17 typeof(Tabs), 18 typeof(Layout) 19 }; 20 } 21 22 protected override bool CanSelectMultipleInstances() 23 { 24 return true; 25 } 26 #endregion 27 28 }
須要重寫CreateNewItemTypes和CanSelectMultipleInstances兩個方法,CreateNewItemTypes是定義容許添加的類型,CanSelectMultipleInstances是告訴設計器orm
是否容許添加多種實例,這裏直接返回true表示容許,效果以下對象
第三個問題翻了半天也看到有啥屬性或方法能夠知足,只能隨便加個變量參數來處理了代碼以下.InstanceCount是用來定義已經添加在集合裏的數量
1 public class SingleItemEditor : ItemCollectionEditor 2 { 3 protected int InstanceCount = 0; 4 #region MyRegion 5 public SingleItemEditor(Type type) : base(type) 6 { 7 8 } 9 10 protected override IList GetObjectsFromInstance(object instance) 11 { 12 if (InstanceCount == 0) 13 { 14 InstanceCount++; 15 return base.GetObjectsFromInstance(instance); 16 } 17 else 18 { 19 return null; 20 } 21 } 22 23 protected override object[] GetItems(object editValue) 24 { 25 InstanceCount = ((dynamic)editValue).Count; 26 return base.GetItems(editValue); 27 } 28 29 protected override void DestroyInstance(object instance) 30 { 31 InstanceCount--; 32 base.DestroyInstance(instance); 33 } 34 35 #endregion 36 37 }
以上三個問題總算所有解決,雖然第三個解決的有些不夠優雅,可是目的還算達到了
PS.一開始在添加編輯器裏添加了Item後發現點肯定保存後再次點擊編輯進去一個Item也沒了,後來發現對於集合屬性,必須得在要編輯的類的構造函數裏先
把這個集合屬性new一個出來,由於CollectionEditor不會幫你實例化集合當沒有集合實例的時候,item固然就沒辦法添加進去了.