草庐IT

c# - UserControl 集合未标记为可序列化

coder 2024-06-01 原文

我一定是遗漏了一些非常明显的东西。我是 C# 的新手,但多年来一直使用 C/C++ 进行编程,如果有明显的问题,我深表歉意;)

[请参阅编辑以了解较新的问题]

我正在尝试创建一个包含 UserControl 的节点。我让 Control 出现在 WinForm 设计器中,我可以向它添加节点。但是,当我尝试运行代码时,出现以下错误:

Code generation for property 'Nodes' failed. Error was: 'Type App.Node' in Assembly 'App, version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

然后我添加的节点都没有出现。

这开始让我发疯了,据我所知,它被标记为可序列化。

节点定义如下:

[Serializable]
public class Node : MarshalByRefObject
{
    public Node()
    {
    }

    public Node( String text )
    {
        this.Text       = text;
        this.Checked    = false;
        this.Complete   = false;
    }

    public String       Text        { get; set; }
    public bool         Checked     { get; set; }
    public bool         Complete    { get; set; }
    public bool         Selected    { get; set; }
};

然后我定义一个“集合”如下:

[Serializable]
public class NodeCollection : List< Node >
{
    public NodeCollection() :
        base()
    {
    }
};

如您所见,集合和节点本身都设置了“Serializable”属性。

报错中提到的Nodes属性定义如下

    private NodeCollection      mNodes  = new NodeCollection();

    [Category( "Behavior" )]
    [Description( "Nodes" )]
    public NodeCollection Nodes
    { 
        get
        {
            return mNodes;
        }
    }

所以有人知道我在这里做错了什么吗?

编辑:作为对 Archeg 评论的回应,这是我的用户控件:

public partial class Control : UserControl
{
    public Control()
    {
        InitializeComponent();
    }

    protected override void OnPaint( PaintEventArgs pe )
    {
        Graphics graph  = pe.Graphics;

        int rowHeight   = Font.Height + 2;

        if ( Nodes != null )
        {
            int yPos    = 0;
            foreach( Node node in this.Nodes )
            {
                // Calculate my various bounding boxes.
                Rectangle nodeBounds    = new Rectangle( Bounds.Left, yPos, Bounds.Width, rowHeight );
                Rectangle lightBounds   = new Rectangle( Bounds.Right - Font.Height, yPos, rowHeight, rowHeight );
                Rectangle spannerBounds = new Rectangle( lightBounds.Left - Font.Height, yPos, rowHeight, rowHeight );
                Rectangle checkBoxBound = new Rectangle( 32, yPos, rowHeight, rowHeight );
                Rectangle textBounds    = new Rectangle( checkBoxBound.Right, yPos, Bounds.Width - (rowHeight * 2) - checkBoxBound.Right, rowHeight );

                // Draw selection box.
                Brush textColour    = Brushes.Black;
                if ( node.Selected )
                {
                    graph.FillRectangle( Brushes.Blue, nodeBounds );
                    textColour      = Brushes.Yellow;
                }

                // Draw node text.
                graph.DrawString( node.Text, Font, textColour, textBounds );

                // Draw Red/Green light
                Image[] lightImages = new Image[] { CompleteLightImage, InCompleteLightImage };
                Image lightImage    = lightImages[node.Complete ? 1 : 0];
                if ( lightImage != null )
                {
                    graph.DrawImage( lightImage, lightBounds );
                }

                // Draw Spanner Icon
                if ( SettingsImage != null )
                {
                    graph.DrawImage( SettingsImage, spannerBounds );
                }
                // Draw check box.
                VisualStyleRenderer renderer    = null;
                VisualStyleElement  ve          = node.Checked ? VisualStyleElement.Button.CheckBox.CheckedPressed : VisualStyleElement.Button.CheckBox.CheckedNormal;
                if (VisualStyleRenderer.IsElementDefined( ve ))
                {
                    renderer = new VisualStyleRenderer( ve );
                }

                if ( renderer != null )
                {
                    renderer.DrawBackground( graph, checkBoxBound );
                }
                else
                {
                    ControlPaint.DrawCheckBox( graph, checkBoxBound, node.Checked ? ButtonState.Checked : ButtonState.Normal );
                }
                yPos    += Font.Height;
            }
        }
    }

    private NodeCollection      mNodes  = new NodeCollection();

    [Category( "Behavior" )]
    [Description( "Nodes" )]
    [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )]
    [MergableProperty( false )]
    [Bindable( false )]
    public NodeCollection Nodes
    { 
        get
        {
            return mNodes;
        }
    }

    public Image CompleteLightImage         { get; set; }
    public Image InCompleteLightImage       { get; set; }
    public Image SettingsImage              { get; set; }
}

自从我最初发布一般与“DesignerSerializationVisibility”属性相关的内容以来,我进行了一些修改,这对我有所帮助,但我现在遇到以下构建错误:

error MSB3103: Invalid Resx file. Could not load type App.Node, App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null which is used in the .RESX file. Ensure that the necessary references have been added to your project.

编辑 2:值得注意的是,我的问题仅在我在设计器中添加一堆节点时出现,然后出现上述 Resx 错误。如果我从代码中手动添加节点,那么一切都会像我期望的那样工作......

最佳答案

我相信您遇到此问题是因为 Designer 会自动尝试序列化所有公共(public) UserControl 属性。如果自定义 UserControl 设计时支持不需要此属性,则可以添加“DesignerSerializationVisibility”属性:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 

或者简单地省略属性的 get{}set{} 方法并将其用作公共(public)字段。

希望对您有所帮助!

关于c# - UserControl 集合未标记为可序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9789066/

有关c# - UserControl 集合未标记为可序列化的更多相关文章

  1. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  2. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  3. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  6. ruby - 在 Ruby 中比较序列 - 2

    假设我必须(小型到中型)阵列:tokens=["aaa","ccc","xxx","bbb","ccc","yyy","zzz"]template=["aaa","bbb","ccc"]如何确定tokens是否以相同的顺序包含template的所有条目?(请注意,在上面的示例中,应忽略第一个“ccc”,从而由于最后一个“ccc”而导致匹配。) 最佳答案 这适用于您的示例数据。tokens=["aaa","ccc","xxx","bbb","ccc","yyy","zzz"]template=["aaa","bbb","ccc"]po

  7. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  8. ruby-on-rails - carrierwave:在序列化动态属性上安装 uploader - 2

    首先,我使用的是rails3.1.3和来自master的carrierwavegithub仓库的分支。我使用after_init钩子(Hook)来确定基于属性的字段页面模型实例并为这些字段定义属性访问器将值存储在序列化哈希中(希望它清楚我是什么谈论)。这是我正在做的事情的精简版:classPage省略mount_uploader命令让我可以访问我想要的属性。但是当我安装uploader时出现错误消息说“nil类的未定义新方法”我在源代码中读到有方法read_uploader和扩展模块中的write_uploader。我如何必须覆盖这些来制作mount_uploader命令使用我的“虚拟

  9. ruby-on-rails - 使用 gmaps4rails 动态加载谷歌地图标记 - 2

    如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail

  10. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

随机推荐