在设计视图中以WinForms应用程序的方式以编程方式添加显示控件?

max*_*axp 2 .net c# windows-forms-designer visual-studio winforms

使用Visual Studio(任何版本都可以),是否可以在切换回设计视图时以编程方式(而不是通过"设计"视图)添加控件?

我尝试过一些非常简单的事情:

public Form1()
{
    AddCtrl();
    InitializeComponent();
    AddCtrl();
}

private void AddCtrl()
{
    this.SuspendLayout();
    this.Controls.Add(new TextBox());
    this.ResumeLayout(false);
    this.PerformLayout();
}
Run Code Online (Sandbox Code Playgroud)

......但无济于事.

虽然我确信以前曾经问过这个问题,但这似乎是一个常见的问题,我似乎无法找到答案!

Rez*_*aei 5

设计师是否运行我的代码?

当表单在设计器中显示时,设计器反序列化表单的代码(Form1.Designer.cs或Form1.cs中的第一个类)并创建表单基类的实例并反序列化InitializeComponent并创建在您的表单中声明的控件类并设置它们的属性.

因此代码Constructor将无法运行.设计者只创建表单基类的实例,而不是查看表单的构造函数.

设计师如何运作的有趣例子

看下面的代码并注意这个问题:

  • ;s 在哪里?
  • 构造Form111111Form1
  • 什么是NotDefinedFunction()
  • 怎么样int i = "xxxxxxxxxx"

即使您创建此类文件,设计器也会正确显示.

using System
using System.Collections.Generic
using System.Drawing
using System.Windows.Forms
namespace Sample
{
    public class Form1:Form
    {
        public Form111111()
        {
            NotDefinedFunction()
            InitializeComponent()
        }
        public void InitializeComponent()
        {
            int i = "xxxxxxxxxx"
            this.textBox1 = new System.Windows.Forms.TextBox()
            this.SuspendLayout()
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(0, 0)
            this.textBox1.Name = "textBox1"
            this.textBox1.Text = "text of text box 1";
            // 
            // Form1
            // 
            this.Controls.Add(this.textBox1)
            this.Name = "Form1"
            this.Text = "Form1"
            this.Size= new Size(250,100)
            this.ResumeLayout(false)
            this.PerformLayout()
        }
        private TextBox textBox1
    }
}
Run Code Online (Sandbox Code Playgroud)

你会看到设计师的形式:

在此输入图像描述

如何在设计时动态添加控件?

如果需要这样的功能,可以在表单的基类的构造函数中创建动态控件,因为基类的构造函数将在设计器中打开子表单时运行,然后它将在设计时运行.

但是您应该知道这些控件是继承的,并且不能使用子窗体的设计器进行更改.

所以只需创建一个Form2:

public Form2()
{
    InitializeComponent();
    AddDynamicControls();
}

private void AddDynamicControls()
{
    this.Controls.Add(
       new TextBox() { 
          Name = "TextBox1", Text = "Dynamic", Location = new Point(100, 0) });
}
Run Code Online (Sandbox Code Playgroud)

构建项目,然后更改Form1要继承的基类Form2:

public class Form1:Form2
Run Code Online (Sandbox Code Playgroud)

结果将是:

在此输入图像描述

还有其他解决方案吗?

如果你想在设计时真正生成一些控件,我想你应该看看T4文本模板.

您可以使用t4模板在设计时生成代码.您可能已经看过Entity Framework .tt模板文件.您可以向Text Template项目添加新项目,并在设计时将生成项目的逻辑放在t4模板中.