如何基于另一个UserControl使用WinForms创建UserControl?

时间:2016-04-13 07:58:38

标签: c# winforms user-controls

我添加了一些截图和步骤,以便在下面重现。

我的数据模型有一个基类,我们称之为CommonThing,它有很多属性。然后,该类的几个专用版本具有其他属性。我现在想要创建一个UI来将数据输入到这个模型中。

我创建了一个UserControl,其中包含所有常见属性的控件,如下所示:

internal partial class CommonThingControl : UserControl {

    public CommonThingControl() {
        InitializeComponent();
    }

    // Controller code
}

这也会添加CommonThingControl.Designer.cs,由GUI设计者填充。

我现在创建了一个SpecialFooThingControl作为UserControl,并将类标题更改为:

internal partial class SpecialFooThingControl : CommonThingControl {

    // implementation
}

当我现在打开GUI设计器中的SpecialFooThingControl时,我看到了CommonThingControl的控件,但它们都被锁定了。我在TableLayoutPanel中有CommonThingControl我要添加内容,但我无法更改任何内容,当我尝试将控件拖到TableLayoutPanel时,鼠标光标变为& #34;禁止停车"标志和VS不让我。当我将TableLayoutPanel的访问者设置为public

时,甚至会发生这种情况

可以通过文档大纲将控件移动到TableLayoutPanel,但是当我重建项目时,它会从UI中消失。

我想用UI设计师实现的目标是不可能的,我是否需要手动设置或者是否有一些我忘了的额外步骤?

这是我做的:

首先,创建了一个用户控件,这很简单。我创建了一个表格布局面板,我将其设置为Protected,因为我想添加它。 Common Control

这是FooControl.cs的代码:

namespace GuiTest {
    public partial class FooControl : UserControl {
        public FooControl() {
            InitializeComponent();
        }
    }
}

FooControl.Designer.cs

namespace GuiTest {
    partial class FooControl {
        /// <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.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
            this.label1 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.tableLayoutPanel1.SuspendLayout();
            this.SuspendLayout();
            // 
            // tableLayoutPanel1
            // 
            this.tableLayoutPanel1.ColumnCount = 2;
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
            this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
            this.tableLayoutPanel1.Controls.Add(this.textBox1, 1, 0);
            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
            this.tableLayoutPanel1.RowCount = 1;
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
            this.tableLayoutPanel1.Size = new System.Drawing.Size(360, 28);
            this.tableLayoutPanel1.TabIndex = 0;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(3, 7);
            this.label1.Margin = new System.Windows.Forms.Padding(3, 7, 3, 0);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(25, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Foo";
            // 
            // textBox1
            // 
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Top;
            this.textBox1.Location = new System.Drawing.Point(34, 3);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(323, 20);
            this.textBox1.TabIndex = 1;
            // 
            // FooControl
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.tableLayoutPanel1);
            this.Name = "FooControl";
            this.Size = new System.Drawing.Size(360, 28);
            this.tableLayoutPanel1.ResumeLayout(false);
            this.tableLayoutPanel1.PerformLayout();
            this.ResumeLayout(false);

        }

        #endregion

        protected System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox textBox1;
    }
}

现在,我添加了BarControlAdding UserControl

现在我在UserControl中将FooControl的延伸范围更改为BarControl.cs

namespace GuiTest {
    public partial class BarControl : FooControl {
        public BarControl() {
            InitializeComponent();
        }
    }
}

BarControl.Designer.cs

namespace GuiTest {
    partial class BarControl {
        /// <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() {
            components = new System.ComponentModel.Container();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        }

        #endregion
    }
}

结果如下: Locked Layout Panel

2 个答案:

答案 0 :(得分:1)

print "Enter user data1: "; my $data1 = <STDIN>; print "Enter user data2: "; my $data2 = <STDIN>; my $sum = $data1 + $data2; 中的控件被锁定的原因是因为子类CommonThingControl无法访问它们(它们是私有范围的)。

然而,在SpecialFooThingControl的设计器中,您可以做的是更改它们上的修饰符属性,这将允许您在子类中使用/修改它们。您需要在每个单独的控件上执行此操作,并且只需更改“属性”窗口中的下拉列表即可。您可以在CommonThingControl文件中更改它们,但是我也会因为自动生成此文件而保持警惕,如果您不小心,更改很容易被覆盖。

enter image description here

我建议使用类似commonthingcontrol.designer.cs的内容,以确保子控件可以看到它们,但防止它们在继承链之外被滥用。

修改

因此,进一步研究这表明这是Protected的限制。取自https://msdn.microsoft.com/en-us/library/ms171689.aspx

  

避免可视继承TableLayoutPanel控件不支持   Windows窗体设计器中的可视继承。一个TableLayoutPanel   派生类中的控件在设计时显示为“锁定”。

答案 1 :(得分:0)

由于控件的可访问性,您无法更新它们。 为此,请进入您的CommonThingControl.Designer.cs,将例如<div class="col-md-5 col-sm-5 col-xs-6 col-xxs-12 fh5co-project to-animate"> <a href="images/work_1.jpg" class="image-popup"> <div class="fh5co-overlay-text">Project no. 1</div> <div class="fh5co-overlay"></div> <img src="images/work_1.jpg" alt="Free HTML5 Template" class="img-responsive"> </a> <div class="carousel-caption"> <h3>Example headline.</h3> </div> </div> 更改为private Button MyButton1