我正在使用Visual C#2008 Express Edition创建WinForms用户控件。
一切都很顺利,直到我发现我可以从属性窗口中使用List<>
集合属性。在尝试更改集合并运行项目之后,我开始收到错误并尽力将所有内容恢复到工作时的状态。
现在,当我尝试将控件的实例放到表单上时,出现以下错误。
Failed to create component 'ColorPicker'. The error message follows:
'System.Runtime.Serialization.SerializationException: Type 'WindowsFormsApplication1.ColorPicker+ColorData' in Assembly 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter)
at System.Runtime.Serialization.Formatt...'
在解除此错误后,我开始反复出现以下错误,直到我使用任务管理器关闭Visual C#为止。
Code generation for property 'PaletteColors' failed. Error was: 'Type 'WindowsFormsApplication1.ColorPicker+ColorData' in Assembly 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.'
我尝试将我的ColorData类标记为[Serializable]
但后来又开始出现其他错误。我不记得确切的细节,但这并不重要,因为我不想将这些数据序列化。
我尝试了一个新表单并得到了同样的错误。所以我创建了一个全新的项目,并将我的类代码复制到新的用户控件,但仍然会出现错误。任何人都可以建议可能导致此错误的原因吗?我不希望这个集合被序列化。
这是有问题的集合(这些是我的用户控件中的行 - ColorData类嵌套在我的用户控件中)。
public List<ColorData> PaletteColors { get; set; }
public class ColorData
{
public string Text { get; set; }
public Color Color { get; set; }
public ColorData()
{
Text = String.Empty;
Color = Color.White;
}
public ColorData(string text, Color color)
{
Text = text;
Color = color;
}
public ColorData(KnownColor color)
{
Text = Enum.GetName(typeof(KnownColor), color);
Color = Color.FromKnownColor(color);
}
public override string ToString()
{
return Text;
}
}
答案 0 :(得分:21)
毫无疑问,设计师无法将一些额外的属性序列化,以便在设计师的表面上展示它。
尝试将这些属性添加到用户控件的非可序列化属性中:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<ColorData> PaletteColors { get; set; }
答案 1 :(得分:3)
您可以使用:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<ColorData> PaletteColors { get; set; }
但如果您的表单已本地化,您也可以添加此内容:
[System.ComponentModel.Localizable(false)]
答案 2 :(得分:2)
如果您想在设计模式中浏览
,可以试试这个[System.Xml.Serialization.XmlArray]
public List<Pen> PenList
{
get { return penList; }
set { penList = value; }
}
答案 3 :(得分:1)
我对此不确定,但您是否尝试过使用[Serializable]属性?
[Serializable]
public class ColorData
{
.....
}
答案 4 :(得分:0)
我在接受的答案中添加了评论,但觉得这可能值得自己回答。虽然公认的答案肯定有效,但并不能真正解决根本原因。
如果您有一个带有公共属性PropertyA的控件(wincontrol),并将其添加到窗体(myForm),则设计器会将属性的所有必要初始化添加到myForm.Designer.cs中。像这样的东西
Wincontrol1.PropertyA = new List<widget>();
需要稍微修改一个控件并不罕见,可以说我们有一个新的控件MyWinControl
public partial class MyWinControl : WinControl
{
public List<wodget> PropertyDer1;
protected List<wodget> PropertyDer2;
}
如果将此新控件替换为myForm.Designer.cs中的旧控件,则很可能会遇到此问题。原因是PropertyDer1在Winforms设计器中没有初始化。 PropertyDer2不会受到任何影响,因为它受到了保护。同样,如果您有一个自定义组件,并且在将该组件添加到表单之后添加了一个新的公共属性。
但是,如果您删除了窗体上的WinControl实例,而是将MyWinControl的实例拖到了窗体上,则会发生正确的初始化,并且您不会看到此错误。设计人员将创建像这样的新控件
Wincontrol1.PropertyA = new List<widget>();
Wincontrol1.PropertyDer1= new List<wodget>();
有两种简单的解决方案,不需要向设计者隐藏属性。 1.如果该属性不需要公开,则给它正确的修饰符 2.如果该属性确实需要公开,则只需像上面的代码一样在myForm.Designer.cs中编辑代码,以添加缺少的初始化器