dia*_*ler 13 .net c# designer properties visual-studio-2010
今天上班时,我偶然发现了一个让我疯狂的问题.
基本上我的目标是:
我有一个UserControl1,具有类型的字段Collection<Class1>和相应的属性Collection<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; }
}
}Run Code Online (Sandbox Code Playgroud)
// later added:
//[Serializable]
public class Class1
{
private bool booltest; public bool Booltest { get...set...}
private int inttest; public int Inttest { get...set...}
}Run Code Online (Sandbox Code Playgroud)
如果你已经知道我搞砸了什么:不需要阅读其余部分.我将描述我究竟做了什么.
现在我把它UserControl放在一个随机的Form上并更改Prop属性.将出现一个通用的"集合编辑器",类似于listview控件中的列和组.我可以按预期输入数据.但是,当我单击"确定"时,数据消失了.
我花了一个多小时才发现我实际上必须实例化我的领域:private Collection<MyClass> field = new Collection<MyClass>();.非常好,只有设计师进入了超级模式.级联噩梦错误信息可以简化为:"你必须放在[Serializable]你的前面Class1." 在这之后,我实际上可以UserControl1再次将我放在表格上.
但那只能工作一次.打开我使用UserControl1后编辑的Form的设计器时,它给了我一个错误:
Object of type 'userctltest.Class1[]' cannot be converted to type 'userctltest.Class1[]'.
好.错误列表说:
Warning: ResX file Object of type 'userctltest.Class1[]' cannot be converted to type 'userctltest.Class1[]'. Line 134, position 5. cannot be parsed.
设计者尝试从resx文件中获取Property的数据.删除resx文件"解决"一次.
表格现在可以再次显示,我的UserControl1.Collection属性是可编辑的,并且正在保存.它确实有效.一旦.每当我更改某些内容然后再次尝试打开Form的设计器时,会再次出现上述错误.我可以删除resx文件,但这当然也会删除我的数据.
到目前为止帮助我的相关资源(在大量不太有用的搜索结果中):
http://www.codeproject.com/Answers/190675/Usercontrol-with-custom-class-property#answer1
http://www.codeproject.com/KB/cs/propertyeditor.aspx
http://www.csharpfriends. com/Articles/getArticle.aspx?articleID = 94
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx
(我也试过实现ISerializable并重写GetObjectData
{ info.AddValue("testbool", testbool); info.AddValue("testint", testint); }
也没有帮助(我也尝试了属性名称而不是字段名称))
对不起写这个像坏恐怖小说顺便说一句.
Pat*_*tko 15
您想要的是CodeDom序列化的设计时支持.您不需要SerializableAttribute或者ISerializable那些用于二进制序列化.由于您要序列化集合,因此必须告诉设计者将其序列化.这是通过DesignerSerializationVisibiliby属性完成的- 值Content告诉设计者序列化属性内容而不是属性本身.该属性的内容当然应该是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; }
}
}
Run Code Online (Sandbox Code Playgroud)
......它应该做的伎俩.哦和集合属性通常是不可写的,虽然这不是强制性的.但是序列化程序期望初始化集合属性,这就是为什么必须为字段添加初始化的原因.另请注意,如果您不希望属性在属性编辑器中标记为粗体,则可以通过特殊方法指定更复杂的"默认值" ShouldSerializePropertyName,该方法甚至可以是私有的.像这样:
private bool ShouldSerializeprop()
{
return (field.Count > 0);
}
Run Code Online (Sandbox Code Playgroud)
现在,您的属性只有在非空时才会变为粗体.但我离题了,这不是一个问题:)