[英]How to add an event to a UserControl in C#?
I have a UserControl which contains 3 labels. 我有一个包含3个标签的UserControl。 I want to add an event for it, which occurs when the text of one of the labels changed.
我想为它添加一个事件,当其中一个标签的文本发生变化时会发生这种事件。
I am using Visual Studio 2010 我正在使用Visual Studio 2010
First, you need to declare the event within your class (alongside your methods and constructors): 首先,您需要在类中声明事件(与方法和构造函数一起):
public event EventHandler LabelsTextChanged;
Then you need to create a method to handle the individual labels' TextChanged
events. 然后,您需要创建一个方法来处理单个标签的
TextChanged
事件。
private void HandleLabelTextChanged(object sender, EventArgs e)
{
// we'll explain this in a minute
this.OnLabelsTextChanged(EventArgs.Empty);
}
Somewhere, probably in your control's constructor, you need to subscribe to the label's TextChanged
events. 某处,可能在您的控件的构造函数中,您需要订阅标签的
TextChanged
事件。
myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;
Now for the HandleLabelsTextChanged
method. 现在为
HandleLabelsTextChanged
方法。 We could raise LabelsTextChanged
directly; 我们可以直接提高
LabelsTextChanged
; however, the .NET framework design guidelines say that is it a best practice to create an OnEventName
protected virtual method to raise the event for us. 但是,.NET框架设计指南说,最好的做法是创建一个
OnEventName
受保护的虚拟方法来为我们引发事件。 That way, inheriting classes can "handle" the event by overriding the OnEventName
method, which turns out to have a little better performance than subscribing to the event. 这样,继承类可以通过重写
OnEventName
方法来“处理”事件,事实证明它比订阅事件具有更好的性能。 Even if you think you will never override the OnEventName
method, it is a good idea to get in the habit of doing it anyway, as it simplifies the event raising process. 即使你认为你永远不会覆盖
OnEventName
方法,但最好还是养成这样做的习惯,因为它简化了事件提升过程。
Here's our OnLabelsTextChanged
: 这是我们的
OnLabelsTextChanged
:
protected virtual void OnLabelsTextChanged(EventArgs e)
{
EventHandler handler = this.LabelsTextChanged;
if (handler != null)
{
handler(this, e);
}
}
We have to check for null because an event without subscribers is null. 我们必须检查null,因为没有订阅者的事件是null。 If we attempted to raise a null event, we would get a
NullReferenceException
. 如果我们尝试引发null事件,我们将得到
NullReferenceException
。 Note that we copy the event's EventHandler
to a local variable before checking it for null and raising the event. 请注意,我们将事件的
EventHandler
复制到局部变量,然后再将其检查为null并引发事件。 If we had instead done it like this: 如果我们这样做了:
if (this.LabelsTextChanged != null)
{
this.LabelsTextChanged(this, e);
}
We would have a race condition between the nullity check and the event raising. 我们会在无效性检查和事件提升之间存在竞争条件。 If it just so happened that the subscribers to the event unsubscribed themselves just before we raised the event but after we checked for null, an exception would be thrown.
如果碰巧事件的订阅者在我们提出事件之前取消订阅,但在我们检查了null之后,将抛出异常。 You won't normally encounter this issue, but it is best to get in the habit of writing it the safe way.
你通常不会遇到这个问题,但最好养成以安全的方式编写它的习惯。
Edit: Here is how the public event EventHandler LabelsTextChanged;
编辑:以下是
public event EventHandler LabelsTextChanged;
line should be placed: 应该放置一行:
namespace YourNamespace
{
class MyUserControl : UserControl
{
// it needs to be here:
public event EventHandler LabelsTextChanged;
...
}
}
Here are the framework design guidelines on event design for further reading. 以下是有关事件设计的框架设计指南,供进一步阅读。
First you should declare an event in your usercontrol for example: 首先,您应该在usercontrol中声明一个事件,例如:
public event EventHandler TextOfLabelChanged;
then you have to call the call back function that is bound to your event(if there's any) in runtime.You can do this by handling the TextChanged event of a label like this: 那么你必须在运行时调用绑定到你的事件(如果有的话)的回调函数。你可以通过处理像这样的标签的TextChanged事件来做到这一点:
public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}
You can have your own EventArgs object if you like. 如果您愿意,可以拥有自己的EventArgs对象。
somewhere in your code you should bound your label TextChanged event to this method like this: 在代码中的某处,您应该将标签TextChanged事件绑定到此方法,如下所示:
_myLabel.TextChanged+=LabelTextChanged;
There is a very simple way to do that! 有一种非常简单的方法可以做到这一点!
On the UserControl Form : 在UserControl表单上:
on the main form , where you are using UserControl: 在主窗体上,您正在使用UserControl:
.5: in the using
region add using userControl1=UserControl.userControl1
.5:在
using
区域添加using userControl1=UserControl.userControl1
1.Add 'Laod' event to your UserControl : 1.将'Laod'事件添加到UserControl:
this.userControl1.Load += new System.EventHandler(this.userControl1_Load);
2.In the userControl1_Load : 2.在userControl1_Load中:
private void userControl1_Load(object sender, EventArgs e)
{
(sender as UserControl1).label1.TextChanged += label1_TextChanged;
//add a 'TextChanged' event to the label1 of UserControl1
OR use direct cast:
((UserControl1) sender).label1.TextChanged += label1_TextChanged;
}
3.In th label1_TextChanged: 3.在label1_TextChanged中:
private void label1_TextChanged(object sender, EventArgs e)
{
//do whatever you want
}
compile error, which says: "Expected class, delegate, enum, interface, or struct" on the second line it seems to have a problem with "event... 编译错误,在第二行显示“预期的类,委托,枚举,接口或结构”,它似乎与“事件......有问题”
These 2 lines need to be INSIDE the class declaration. 这两行需要在INSIDE类声明中。
public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;
You must be declaring the event
and delegate
within the Namespace
. 您必须在
Namespace
声明event
和delegate
。 Try to bring the code within the class
Scope. 尝试将代码放在
class
Scope中。 It will run fine. 它运行正常。
public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;
// ...
protected void MyTextBox_TextChanged(object sender, EventArgs e)
{
if (LabelTextChanged != null) {
LabelTextChanged(this, e);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.