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

Show controls added programmatically in WinForms app in Design view?

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

我试过一些非常简单的方法,比如:

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

private void AddCtrl()
{
    this.SuspendLayout();
    this.Controls.Add(new TextBox());
    this.ResumeLayout(false);
    this.PerformLayout();
}

...但无济于事。

设计者运行我的代码吗?

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

所以 Constructor 中的代码不会 运行。设计者只创建表单基础 class 的实例,而不查看表单的构造函数。

设计师工作方式的有趣示例

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

  • ;在哪里?
  • Form1 的构造函数 Form111111?
  • 什么是 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
    }
}

您将在设计器中看到表单:

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

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

但是你应该知道这些控件是继承的,不能使用子窗体的设计器来更改。

所以简单地创建一个 Form2:

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

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

构建项目,然后将 Form1 的基础 class 更改为继承自 Form2:

public class Form1:Form2

结果将是:

还有其他解决办法吗?

如果你真的想在设计时生成一些控件,我认为你应该看看 T4 Text Templates

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