如何设置用户控件的默认事件? [英] How to set the defaul event for a user control?

查看:64
本文介绍了如何设置用户控件的默认事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个带有事件的用户控件.我不想每次将控件的新实例添加到表单时都添加以下代码.

I created a user control with an event. I do not want to add the following code every time I add a new instance of the control to a form.

Control1.Operate += new MyControl.OperateEventHandler(Control1_Operate)



相反,我只想双击该控件,然后将上述代码由IDE添加到Designer文件中.默认情况下,Control1_Load事件在设计器文件中分配.



Instead I would like to simply double-click the control and have the above code added by the IDE to the Designer file. By default the Control1_Load event is assigned in the Designer file. Is it possible to change this?

推荐答案

您需要设置一个属性.它将其设置为Click事件:
You need to set an attribute. This sets it to the Click event:
[System.ComponentModel.DefaultEvent("Click")]
public partial class MyUserControl : UserControl
    {
    ...
    }


只是警告提示:

太好了,以致System.ComponentModel不是标准.NET库的一部分(标准"是指ECMA和ISO下的标准化).有些.NET库很棒,有些则不太好.根据我所知,System.ComponentModel是最差的一个.

参加此类System.ComponentModel.DefaultEventAttribute.它需要立即数或显式字符串常量作为其参数.从可维护性的角度来看,这是最坏的情况.如果字符串作为参数拼写错误通过而传递,则编译器将无法检查任何内容并发出单个警告,但是Designer下组件的行为将被修改.一些属性类的构造函数需要静态已知的类型(因此,通过typeof传递);它不允许提供任何类型约束,但至少编译器可以检查这是否是确实存在的类型.这也很糟糕,但不如字符串常量那么糟糕.

对于System.ComponentModel,始终使用这种烂方法.我的意思是:这不是反射的问题,在这种情况下,可以从类型中提取元数据而无需使用任何字符串常量(如成员名)(这也是可能的),这是System.ComponentModel的问题.存在一些与属性和System.Type的限制有关的根本问题(不是完全成熟的元类),但是尽管如此,大多数.NET库都没有System.ComponentModel.
我还在文章人类可读的枚举元数据 [ ^ ].

我建议任何人不要为System.ComponentModelForms设计时行为而奋斗.微软已经提供了两种新的用户界面模型.谁知道呢? FormsSystem.ComponentModel的预期寿命可能不值得浪费我们的精力来朝这个方向努力吗?我们在工作时间上的投资可能永远无法回报……

—SA
Just a note of warning:

This is so good that System.ComponentModel is not a part standard .NET library (by "standard" I mean standardization under ECMA and ISO). Some .NET libraries are wonderful, some are not so good; and System.ComponentModel is the worse one from what I know.

Take this class System.ComponentModel.DefaultEventAttribute. It requires either immediate or explicit string constant as its argument. This is the worst case from the maintainability standpoint. If the string passes as a parameter is misspelled, a compiler cannot checkup anything and issue a single warning, but the behavior of the component under Designer will be modified. Some constructor of attribute classes require statically known type (hence, passed through typeof); it does not allow to provide any type constraint, but at least the compiler can check up if this is a really existing type. This is bad, too, but not as bad as a string constant.

With System.ComponentModel, such rotten technique is used all the time. I mean it: this is not a problem of Reflection, where the meta-data can be extracted from a type without using any string constants like member names (which is also possible), this is a problem of System.ComponentModel. There are fundamental problems related to limitations of attributes and System.Type (not quite a fully-fledged meta-class), but nevertheless most .NET libraries are free from System.ComponentModel.

I also explain some of related problems in my article Human-readable Enumeration Meta-data[^].

I would recommend anyone not to do much effort struggling with System.ComponentModel and Forms Design-time behavior. Microsoft already provided two new UI models; and who knows? may be life time expectancy of Forms and System.ComponentModel does not deserve wasting our lives on working to much in this direction? Our investment in our working time may never pay off…

—SA


OriginalGriff的回答以及SAK对System.ComponentModel的雄辩性批评,是理智的fe盛宴,它很可能会给您带来惊喜实现解决方案所需的所有工具.

但是,我将毫不留情地走到这里,提出建议".

而且,我希望您能原谅我,如果我通过苏格拉底式的方法做到这一点……对我以及您而言,对我来说都是一次实验",因为对我而言,知道是否通过实验,我暗示的是什么与您共鸣".

让我问您一个简单的实验:

1.创建一个WinForms项目,向该项目添加一个UserControl模板,将一个TextBox插入UserControl模板"textBox1".将textBox1的文本保留为"blank".

2.在该UserControl的Load事件中,放入以下一行代码:
OriginalGriff''s answer, and SAK''s eloquent critique of System.ComponentModel, are a feast for the intellect, and may well give you all the tools you need to achieve your solution.

But, I''m going to go, recklessly, ''out on a limb'' here, and suggest a very different approach to this.

And, you''ll forgive me, I hope, if I do this via Socratic method ... an ''experiment'' for me, as well as you, perhaps ... since it would be interesting to me to know if what (I hope) I am implying by experimentation "resonates" with you.

Let me just ask to you do a simple experiment:

1. create a WinForms project, add a UserControl template to the project, insert one TextBox into the UserControl template, ''textBox1.'' Leave the Text of textBox1 ''blank.''

2. in the Load event of that UserControl put this one line of code:
textBox1.Text = "uc loaded";

3.构建项目.

4.在设计时,将已编译的UserControl的一个实例拖放到Form的表面上.

5.观察UserControl的textBox1中显示的内容.

6.从窗体中删除设计时放置的UserControl.

7.在表单上放置一个按钮,并将其单击处理程序设置为:

3. Build the project.

4. at design-time drag-drop an instance of the compiled UserControl onto the surface of the Form.

5. observe what appears in textBox1 of the UserControl.

6. delete the design-time placed UserControl from the Form.

7. put a button on the Form and set its click handler to:

private void button1_Click(object sender, EventArgs e)
{
    UserControl1 uc1 = new UserControl1();
    this.Controls.Add(uc1);
}

8.再次观察出现在UserControl的textBox1中的内容.

9.现在:更改UserControl的Load事件中的代码:

8. once again observe what appears in the textBox1 of the UserControl.

9. Now: alter the code in the UserControl''s Load event:

textBox1.Text = "uc loaded : " + this.Parent.Name;

10.现在再次构建项目并将UserControl的实例拖放到Form曲面上:观察textBox1中的内容.

11.现在,从窗体中删除拖放的UserControl并运行项目,然后单击Form中的button1,以在代码中创建一个新的UserControl:

12.观察UserControl中的textBox1的内容

讨论:

0.请注意,上述实验不需要为Form或UserControl引用System.ComponentModel.

1.为什么用大炮射蝇?即,为什么要使用Attributes和System.ComponentModel ...如果有更简单的方法呢?

2.现在,您知道(我希望)是在设计时将UserControl拖放到Form上,还是在运行时创建UserControl时,将触发其Load事件,并在该Load事件中...访问可用于创建它的对象(在本例中为Form).

3.我假设发布/公开某种方法或在Form上的任何内容所需的技术...因此可以从Form定义范围之外的Form实例中获得该技术...是显而易见的.给你.

我很想知道这里提出的建议是否似乎是解决您所提出问题的基础.而且,如果判决要求,我准备喝铁杉:)

实验性的,比尔

10. Now once again build the Project and drag-drop an instance of the UserControl onto the Form surface: observe what''s in textBox1.

11. Now delete the drag-dropped UserControl from the Form and run the project, and click on button1 in the Form that creates a new UserControl in code:

12. Observe the contents of textBox1 in the UserControl

Discussion:

0. note that the experiment described above does NOT require a reference to System.ComponentModel for either Form or UserControl.

1. why use a cannon to shoot a horse-fly ? i.e., why get involved with Attributes and System.ComponentModel ... if there''s a simpler way ?

2. You now know (I hope) that whether a UserControl is drag-dropped on a Form at design-time, or created at run-time, its Load event is fired, and ... in that Load event ... access is available to the object (in this case a Form) that is creating it.

3. I''ll assume that the technique required to publish/expose some method or whatever on a Form ... so it''s available from an instance of the Form from outside the scope of the Form definition ... is obvious to you.

I''d be very interested to know if what is suggested here seems like a basis for a solution to the question you ask. And, I''m ready to drink the hemlock if the verdict requires it :)

experimentally yours, Bill


这篇关于如何设置用户控件的默认事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆