无法创建组件..类型未标记为可序列化

时间:2011-02-11 20:06:03

标签: c# winforms serialization user-controls

我正在使用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;
    }
}

5 个答案:

答案 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中编辑代码,以添加缺少的初始化器