CollectionEditor集合编辑器使用
最近遇到一个项目需要使用的propertyGrid来让用户自定义属性,在遇到对集合进行操作的的时候遇到几个问题:
1.在集合编辑器上,属性设计区域下面的没有属性描述区域,导致有的用户无法知道这个属性有啥用,如下图
2.集合编辑器只能指定同一个类型,但有个需求是需要在一个集合里添加基于同一个基类的不同拓展的多个类型
3.需要限制集合编辑器Items的数量,不能超过指定数量.
先处理第一个问题,老规矩,遇到问题的时候先google下,结果没找到我需要的,只能老老实实去看看源码希望能有点收货,运气还好,反编译了下CollectionEditor,发现其实
是有描述区域的,只是不知道微软咋想的,默认是不显示的,但是可以通过反射使其显示,具体代码直接贴上
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 }
下面是效果
第二个问题也是通过源码+测试搞定,直接上代码
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是告诉设计器
是否允许添加多种实例,这里直接返回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当然就没办法添加进去了.