在设计时在 Form.cs 中生成自定义 C# 代码,同时在 Form1.cs 中删除用户控件

Generate custom C# code in Form.cs while dropping user control in Form1.cs at design time

我有一个可以在 Form1.cs[设计] 模式下拖放的用户控件。设计器将在 Form1.Designer.cs

中为此用户控件自动生成代码

我还想得到的是:目前我通过拖动将用户控件添加到表单中我不会在我的 Form.cs 中生成指向属性和控件的代码该用户控件。

用户控件示例:

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

    public string TextInTextBox
    {
        get { return textBox1.Text; }
        set { textBox1.Text = value; }
    }
}

所以现在当我将它拖到 Form1.cs[设计] 中的表单上时。我不会在 Form1.cs:

中生成这样的部分代码
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        AddText();
    }

    // this code below to be auto-generated
    private void AddText()
    {
        userControl11.TextInTextBox = "";
    }
}

我想我应该寻找继承或接口之类的东西,但我希望该用户控件的每个实例都出现这种情况。 如果有人能指出我要寻找的方向,那就太好了。谢谢

从工具箱中删除控件时,如果要分配 属性,通常不需要手动生成代码,例如,您可以轻松地执行此操作:

public MyUserControl()
{
    InitializeComponent();
    MyTextProperty = "Something";
}

并且会自动序列化。

但是对于更高级的选项还有更多选项requirements.if你知道你有哪些选项,你可以根据你的要求来选择。这里有一些选项:

  • 在构造函数中或给 属性
  • 赋值
  • 使用 ToolboxItem 为属性赋值,它将覆盖您在构造函数中赋值的值。
  • 为表单的 Load 事件生成一些代码并在那里初始化 属性。它对复杂的代码生成很有用,例如当你删除一个数据源时它会生成一些代码来加载数据并添加到表单的加载事件中。

假设你已经在构造函数中将Something赋值给MyTextProperty,那么当你在表单中删除控件时,下面是designer.cs中将生成的内容:

this.myUserControl1.MyTextProperty = "Something";

如果您使用 ToolboxItem 解决方案将 Something else 分配给 属性,designer.cs 文件中的结果将是:

this.myUserControl1.MyTextProperty = "Something else";

如果您决定使用第三个选项并生成事件处理程序代码,designer.cs 文件中的结果将是:

this.Load += new System.EventHandler(this.Form1_Load);

cs 文件中的结果将是:

private void Form1_Load(object sender, EventArgs e)
{
    myUserControl1.MyTextProperty = "Even something else!";
}

例子

这里是MyUserControlMyUserControlToolboxItemMyUserControlDesigner的完整代码。您可以评论 Designer and/or ToolboxItem 属性并关闭所有设计器并清理并重建解决方案并将控件的实例拖放到窗体上以查看其工作原理。

using System.CodeDom;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;

[Designer(typeof(MyUserControlDesigner))]
[ToolboxItem(typeof(MyUserControlToolBoxItem))]
public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
    }
    public string MyTextProperty { get; set; } = "Something";
}

public class MyUserControlToolBoxItem : ToolboxItem
{
    protected override IComponent[] CreateComponentsCore(IDesignerHost host)
    {
        IComponent[] componentsCore = base.CreateComponentsCore(host);
        if (componentsCore != null && componentsCore.Length > 0
            && componentsCore[0] is MyUserControl)
            (componentsCore[0] as MyUserControl)
                .MyTextProperty = "Something else"; ;
        return componentsCore;
    }
}

public class MyUserControlDesigner : ControlDesigner
{
    public override void InitializeNewComponent(IDictionary defaultValues)
    {
        base.InitializeNewComponent(defaultValues);
        var component = Control;
        var eventBindingService = (IEventBindingService)this.GetService(
            typeof(IEventBindingService));
        var componentChangeService = (IComponentChangeService)this.GetService(
            typeof(IComponentChangeService));
        var designerHostService = (IDesignerHost)GetService(typeof(IDesignerHost));
        var rootComponent = designerHostService.RootComponent;
        var uiService = (IUIService)GetService(typeof(IUIService));
        var designerTransaction = (DesignerTransaction)null;
        try
        {
            designerTransaction = designerHostService.CreateTransaction();
            var e = TypeDescriptor.GetEvents(rootComponent)["Load"];
            if (e != null)
            {
                var methodName = "";
                var eventProperty = eventBindingService.GetEventProperty(e);
                if (eventProperty.GetValue(rootComponent) == null)
                {
                    methodName = eventBindingService
                        .CreateUniqueMethodName(rootComponent, e);
                    eventProperty.SetValue(rootComponent, methodName);
                }
                else
                    methodName = (string)eventProperty.GetValue(rootComponent);
                var code = this.GetService(typeof(CodeTypeDeclaration))
                        as CodeTypeDeclaration;
                CodeMemberMethod method = null;
                var member = code.Members.Cast<CodeTypeMember>()
                    .Where(x => x.Name == methodName).FirstOrDefault();
                if (member != null)
                {
                    method = (CodeMemberMethod)member;
                    method.Statements.Add(
                        new CodeSnippetStatement($"{Control.Name}" +
                        $".MyTextProperty = \"Even something else!\";"));
                }
                componentChangeService.OnComponentChanged(rootComponent,
                    eventProperty, null, null);
                eventBindingService.ShowCode(rootComponent, e);
            }
            designerTransaction.Commit();
        }
        catch (System.Exception ex)
        {
            if (designerTransaction != null)
                designerTransaction.Cancel();
            uiService.ShowError(ex);
        }
    }
}