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

问题描述 投票:14回答:5

我正在使用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;
    }
}
c# winforms serialization user-controls
5个回答
22
投票

毫无疑问,某些额外的属性不能被设计人员序列化以在设计器表面上显示它。

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

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

3
投票

您可以使用此:

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

但是如果您的表单已本地化,也可以添加此内容:

 [System.ComponentModel.Localizable(false)]

2
投票

如果您希望在设计模式下可以浏览,可以尝试此操作

[System.Xml.Serialization.XmlArray]
    public List<Pen> PenList
    {
        get { return penList; }
        set { penList = value; }
    }

0
投票

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

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

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中的代码以添加缺少的初始化程序]

© www.soinside.com 2019 - 2024. All rights reserved.