【问题标题】:Custom Control Doesn't Update in Visual Studio Designer自定义控件在 Visual Studio 设计器中不更新
【发布时间】:2012-09-06 23:25:00
【问题描述】:

我正在创建一个布局单选按钮的自定义控件(不,它不一定是单选按钮。我只是想学习如何做到这一点,以便我可以在路上制作一些更复杂的东西可能包含多个控件列表)通过 Items 属性添加(类似于其他一些控件)。

我可以构建项目,将其从组件面板拖到表单上,并通过 Items 属性添加单选按钮。不幸的是,这在设计器中没有更新,除非您:

  • 重建项目 2-3 次
  • 在设计器中关闭并重新打开表单

起初我的逻辑是在 Initialize 之后将它们放在构造函数中包含的表单上,但这不起作用,所以我转到了 Form_Load。

我错过了什么?上述选项只是短期解决方法,而不是解决方案。

RBLTest.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WFCL_Library
{
    public partial class RBLTest : UserControl
    {
        private List<RadioButton> _items;

        private int leftSpacing = 100;
        private int topSpacing = 25;

        public RBLTest()
        {
            _items = new List<RadioButton>();
            InitializeComponent();
        }

        private void RadioButtonList_Load(object sender, EventArgs e)
        {
            int curLeftPos = 0;
            int curTopPos = 0;
            foreach (RadioButton rb in _items)
            {
                rb.Location = new Point(curLeftPos, curTopPos);
                rb.Size = new Size(85, 17);

                curLeftPos += leftSpacing;

                if (curLeftPos > this.Width)
                {
                    curLeftPos = 0;
                    curTopPos += topSpacing;
                }

                this.Controls.Add(rb);                
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public List<RadioButton> Items
        {
            get
            {
                return _items;
            }
            set
            {
                _items = value;
            }
        }
    }       
}

RBLTest.Designer.cs

namespace WFCL_Library
{
    partial class RBLTest
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // RBLTest
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Name = "RBLTest";
            this.Size = new System.Drawing.Size(407, 44);
            this.Load += new System.EventHandler(this.RadioButtonList_Load);
            this.ResumeLayout(false);

        }

        #endregion

    }
}

【问题讨论】:

    标签: c# winforms visual-studio-2008 .net-3.5 windows-forms-designer


    【解决方案1】:

    您不应使用Load 事件或构造函数,因为当您使用设计器工具添加控件时,会创建UserControl 的实例并触发Load 事件。在您发生这种情况时,_item 仍然是空的。另一个问题是序列化列表存在一些问题,所以我会使用数组:

    public partial class RBLTest : UserControl {
        private RadioButton[] _items;
    
        private int leftSpacing = 100;
        private int topSpacing = 25;
    
        public RBLTest( ) {
            InitializeComponent( );
        }
    
        [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )]
        public RadioButton[] Items {
            get {
                return _items;
            }
            set {
                _items = value;
    
                int curLeftPos = 0;
                int curTopPos = 0;
                foreach ( RadioButton rb in _items ) {
                    rb.Location = new Point( curLeftPos, curTopPos );
                    rb.Size = new Size( 85, 17 );
    
                    curLeftPos += leftSpacing;
    
                    if ( curLeftPos > this.Width ) {
                        curLeftPos = 0;
                        curTopPos += topSpacing;
                    }
    
                    this.Controls.Add( rb );
                }
            }
        }
    }
    

    表单设计器中的结果:

    【讨论】:

    • Ohhhhhhhhhhhh 我现在只想拥抱你,我花了这么长时间玩弄这个,但没有运气用我糟糕的谷歌搜索找到任何关于这个主题的东西。您是否碰巧参考了一篇讨论在设计器中序列化通用列表的问题的文章?
    • 哈哈 :) 很高兴为您提供帮助!
    • @Mohgeroth 你不需要另一个集合,你已经在 Controls 集合中有一个集合,无论如何你的子控件都必须存在。
    • 不,我从未使用过列表,我不知道是否可行,但如果您需要列表,您可以在属性设置器中进行操作:List&lt;RadioButton&gt; list = _items.ToList();
    【解决方案2】:

    原因是您仅在 Load 事件中向 ControlsCollection 添加控件。这是我在 Google 上搜索的在 WinForms 中创建容器控件的教程: http://www.codeproject.com/Articles/9238/WinForms-Custom-Container-Control

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多