首页 > 解决方案 > 从工具箱拖放自定义控件时生成代码或事件

问题描述

我正在创建一个自定义控件(例如自定义 LookUpEdit),我想知道当我将这个控件拖放到里面时,我是否可以自动生成代码(例如 form.cs 文件中的 EditValueChanged 事件或一些代码行,例如 Form_Load 事件中)表单设计器,让任何开发人员都有机会轻松查看和扩展此代码(如果他/她愿意)。

我的问题是:在设计时从工具箱中拖放自定义控件时,如何在表单(form.cs)中自动生成代码或事件?

标签: c#visual-studiowinformscustom-controlswindows-forms-designer

解决方案


有时您可能希望在表单上放置组件时生成一些代码。例如,当您将数据源从数据源窗口拖放到表单上时,您会看到类似的行为。

这种行为对于扩展和加载项更为常见,但您也可以在从工具箱中删除组件时为您的组件实现此类行为。

答案的关键点是:

例子

MyControl在这个例子中创建了一个控件。当您将控件的实例拖放到窗体上时,设计器将为其Click事件生成以下代码:

private void myControl1_Click(object sender, EventArgs e)
{
    MessageBox.Show("Hi!");

}

这是 和 的MyControl代码MyControlDesigner。您可能希望在代码中添加空值检查。

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

[Designer(typeof(MyControlDesigner))]
public partial class MyControl : Control
{
}

public class MyControlDesigner : ControlDesigner
{
    public override void InitializeNewComponent(IDictionary defaultValues)
    {
        base.InitializeNewComponent(defaultValues);
        var component = this.Component;
        var eventBindingService = (IEventBindingService)this.GetService(
            typeof(IEventBindingService));
        var componentChangeService = (IComponentChangeService)this.GetService(
            typeof(IComponentChangeService));
        var designerHostService = (IDesignerHost)GetService(typeof(IDesignerHost));
        var uiService = (IUIService)GetService(typeof(IUIService));
        var designerTransaction = (DesignerTransaction)null;
        try
        {
            designerTransaction = designerHostService.CreateTransaction();
            var e = TypeDescriptor.GetEvents(component)["Click"];
            if (e != null)
            {
                var methodName = eventBindingService.CreateUniqueMethodName(component, e);
                var eventProperty = eventBindingService.GetEventProperty(e);
                if (eventProperty.GetValue(component) == null)
                {
                    eventProperty.SetValue(component, methodName);
                    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("MessageBox.Show(\"Hi!\");"));
                    }
                    componentChangeService.OnComponentChanged(component,
                        eventProperty, null, null);
                    eventBindingService.ShowCode(component, e);
                }
            }
            designerTransaction.Commit();
        }
        catch (System.Exception ex)
        {
            if (designerTransaction != null)
                designerTransaction.Cancel();
            uiService.ShowError(ex);
        }
    }
}

推荐阅读