c# – 如何使Form类型的用户控件属性可在Form Designer中编辑?
今天在工作中,我偶然发现了一个让我疯狂的问题.
基本上我的目标是这样的: 我有一个UserControl1,一个类型为Collection< Class1>的字段和相应的属性集合< Class1> Prop.像这样: public class UserControl1 : UserControl { private Collection<Class1> field = null; // later changed to: //private Collection<Class1> field = new Collection<Class1>(); [Category("Data")] [DefaultValue(null)] [Description("asdf")] public Collection<Class1> prop { get { return field; } set { field = value; } } } // later added: //[Serializable] public class Class1 { private bool booltest; public bool Booltest { get...set...} private int inttest; public int Inttest { get...set...} } 如果你已经知道我搞砸了什么:不需要阅读其余的内容.我要描述我究竟做了什么 现在我把UserControl放在一个随机的Form中,并改变了Prop属性.出现一个通用的“集合编辑器”,就像列表视图控件中的列和组一样.我可以按预期输入数据.但是,当我单击确定,数据已经消失. 我花了一个多小时才弄清楚,我实际上必须实例化我的字段:private Collection< MyClass> field = new Collection< MyClass>();.非常好,只有设计师进入超级喷雾模式.级联的噩梦错误消息可以减少为:“您必须将[Serializable]放在Class1之前.做完之后,我可以把我的UserControl1放在Form上了. 但这只能奏效一次.当打开Form的设计者时,我在使用UserControl1后,编辑一些东西,它给我一个错误: “userctltest.Class1 []”类型的对象无法转换为类型’userctltest.Class1 []’. 好.错误列表说: 警告:ResX文件类型’userctltest.Class1 []’的对象无法转换为类型’userctltest.Class1 []’.第134行,位置5.无法解析. 设计人员尝试从resx文件中获取该属性的数据.删除resx文件“解决”一次. 现在可以使用我的UserControl1再次显示该表单. Collection属性是可编辑的,并且正在被保存.它实际上是有效的.一旦.每当我改变一些东西,然后再次尝试打开Form的设计师,上面的错误再次出现.我可以删除resx文件,但这当然也会删除我的数据. 帮助我的相关资源到目前为止(在一吨不太有用的搜索结果中): http://www.codeproject.com/Answers/190675/Usercontrol-with-custom-class-property#answer1 (我也尝试实现ISerializable并覆盖GetObjectData {info.AddValue(“testbool”,testbool); info.AddValue(“testint”,testint); } 没有帮助(我也尝试了属性名称而不是字段名称)) 对不起,写这个像一个坏的恐怖小说btw. 解决方法
您想要的是使用CodeDom序列化的设计时间支持.您不需要SerializableAttribute或ISerializable,那些用于二进制序列化.
既然你想序列化集合,你必须告诉设计者把它序列化.这是通过 DesignerSerializationVisibiliby属性 – 值的内容来告诉设计者序列化属性内容而不是属性本身.属性的内容当然应该是CodeDom可序列化的,默认情况下,简单属性的简单类. 所以如果你这样改变你的UserControl1类: public class UserControl1 : UserControl { private Collection<Class1> field = new Collection<Class1>(); [Category("Data")] [Description("asdf")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public Collection<Class1> prop { get { return field; } } } …应该做的伎俩哦和收藏属性通常是不可写的,虽然这不是强制性的.但是串行器期望收集属性被初始化,这就是为什么你必须添加字段的初始化. private bool ShouldSerializeprop() { return (field.Count > 0); } 现在你的财产只有当它不是空时才是粗体.但我离题,这不是问题:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |