C# 未能创建组件。。类型未标记为可序列化

C# 未能创建组件。。类型未标记为可序列化,c#,winforms,serialization,user-controls,C#,Winforms,Serialization,User Controls,我正在使用Visual C#2008 Express Edition创建WinForms用户控件 一切都进行得很顺利,直到我发现我可以从属性窗口使用列表集合属性。在尝试更改集合并运行项目后,我开始出现错误,并尽最大努力将所有内容恢复到工作时的状态 现在,当我尝试将控件的一个实例放在窗体上时,我得到以下错误 Failed to create component 'ColorPicker'. The error message follows: 'System.Runtime.Serializat

我正在使用Visual C#2008 Express Edition创建WinForms用户控件

一切都进行得很顺利,直到我发现我可以从属性窗口使用
列表
集合属性。在尝试更改集合并运行项目后,我开始出现错误,并尽最大努力将所有内容恢复到工作时的状态

现在,当我尝试将控件的一个实例放在窗体上时,我得到以下错误

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

我尝试将ColorData类标记为
[Serializable]
,但随后开始出现其他错误。我记不起确切的细节,但这并不重要,因为我不希望这些数据序列化

我尝试了一个新的表单,但得到了相同的错误。因此,我创建了一个全新的项目,并将类的代码复制到一个新的用户控件上,错误仍然存在。有人能指出是什么导致了这个错误吗?我不希望此集合序列化

这里是有问题的集合(这些是我的用户控件中的行——ColorData类嵌套在我的用户控件中)

公共列表调色板颜色{get;set;}
公共类彩色数据
{
公共字符串文本{get;set;}
公共颜色{get;set;}
公共数据()
{
Text=String.Empty;
颜色=颜色。白色;
}
公共颜色数据(字符串文本、颜色)
{
文本=文本;
颜色=颜色;
}
公共颜色数据(已知颜色)
{
Text=Enum.GetName(typeof(KnownColor),color);
颜色=颜色。FromKnown颜色(颜色);
}
公共重写字符串ToString()
{
返回文本;
}
}

我对此不确定,但您是否尝试过使用[Serializable]属性

[Serializable]
public class ColorData
{
.....
}

毫无疑问,一些额外的属性不可由设计器序列化以在设计器表面上显示

尝试将这些属性添加到用户控件的不可序列化属性:

[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<ColorData> PaletteColors { get; set; } 
[可浏览(错误)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
公共列表调色板颜色{get;set;}
您可以使用以下功能:

[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<ColorData> PaletteColors { get; set; }

如果你想在设计模式下浏览,你可以试试这个

[System.Xml.Serialization.XmlArray]
    public List<Pen> PenList
    {
        get { return penList; }
        set { penList = value; }
    }
[System.Xml.Serialization.XmlArray]
公开名单
{
获取{return penList;}
设置{penList=value;}
}

我在被接受的答案中添加了一条评论,但我觉得这可能值得给出自己的答案。虽然公认的答案确实有效,但它并没有真正解决根本原因

如果您有一个带有公共属性PropertyA的控件(wincontrol),并将其添加到表单(myForm),则设计器会将所有必要的属性初始化添加到myForm.designer.cs中。有点像

Wincontrol1.PropertyA = new List<widget>();
Wincontrol1.PropertyA=新列表();
需要稍微修改控件的情况并不少见,假设我们有一个新控件MyWinControl

public partial class MyWinControl : WinControl
{
    public List<wodget> PropertyDer1;
    protected List<wodget> PropertyDer2;
}
公共部分类MyWinControl:WinControl
{
公共财产清单1;
受保护的清单财产2;
}
如果您在myForm.Designer.cs中将此新控件替换为旧控件,则很可能会遇到此问题。原因是PropertyDr1在winforms设计器中没有初始化。PropertyDer2不会引起任何问题,因为它受到保护。类似地,如果您有一个自定义组件,并且在将该组件添加到表单后添加了一个新的公共属性

但是,如果您删除了窗体上的WinControl实例,并将MyWinControl实例拖到窗体上,则会发生正确的初始化,您不会看到错误。设计器将创建如下的新控件

Wincontrol1.PropertyA = new List<widget>();
Wincontrol1.PropertyDer1= new List<wodget>();
Wincontrol1.PropertyA=新列表();
Wincontrol1.PropertyDer1=新列表();
有两种简单的解决方案不需要对设计器隐藏属性。 1.如果属性不需要是公共的,请为其指定正确的修饰符
2.如果属性确实需要是公共的,那么只需像上面的代码那样编辑myForm.Designer.cs中的代码,添加缺少的初始值设定项

我在问题中解释过我这样做了。这与OP所寻找的相反。它不可序列化并不奇怪,VisualStudio认为它应该是可序列化的!我对你感激不尽。这真让我抓狂!进行请求的更改修复了问题。关于用户控件属性,我显然有点不知所措。我会研究这些设置,但也许你会分享你的想法,为什么这会有帮助。谢谢。另外,如果房产不需要公开,也不要这样做。我的一处房产本可以得到保护,却被懒洋洋地标记为公共。只需将其设置回受保护状态,即可解决此问题。我希望实际初始化myform.designer.cs中控件的属性可以修复它。当我在一个窗体上有一个控件时,我通常会遇到这个问题,我将它分为另一个从它继承的控件。如果您刚刚添加了第二个控件,那么VS将添加必要的初始值设定项
Wincontrol1.PropertyA = new List<widget>();
public partial class MyWinControl : WinControl
{
    public List<wodget> PropertyDer1;
    protected List<wodget> PropertyDer2;
}
Wincontrol1.PropertyA = new List<widget>();
Wincontrol1.PropertyDer1= new List<wodget>();