如何在C#中向UserControl添加事件?
我有一个UserControl,它包含3个标签。我想为它添加一个事件,当其中一个标签的文本更改时会发生该事件。如何在C#中向UserControl添加事件?,c#,winforms,events,user-controls,C#,Winforms,Events,User Controls,我有一个UserControl,它包含3个标签。我想为它添加一个事件,当其中一个标签的文本更改时会发生该事件。 我正在使用Visual Studio 2010首先,您应该在usercontrol中声明一个事件,例如: public delegate void TextChangedEventHandler(object sender, EventArgs e); public event TextChangedEventHandler LabelTextChanged; // ... pro
我正在使用Visual Studio 2010首先,您应该在usercontrol中声明一个事件,例如:
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);
}
}
public event EventHandler TextOfLabelChanged;
然后,您必须在运行时调用绑定到事件(如果有)的回调函数。您可以通过如下方式处理标签的TextChanged事件:
public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}
_myLabel.TextChanged+=LabelTextChanged;
if (this.LabelsTextChanged != null)
{
this.LabelsTextChanged(this, e);
}
如果愿意,您可以拥有自己的EventArgs对象
在代码的某个地方,您应该将label TextChanged事件绑定到此方法,如下所示:
public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}
_myLabel.TextChanged+=LabelTextChanged;
if (this.LabelsTextChanged != null)
{
this.LabelsTextChanged(this, e);
}
首先,需要在类中声明事件(与方法和构造函数一起): 然后,您需要创建一个方法来处理单个标签的
TextChanged
事件
private void HandleLabelTextChanged(object sender, EventArgs e)
{
// we'll explain this in a minute
this.OnLabelsTextChanged(EventArgs.Empty);
}
myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;
在某个地方,可能在控件的构造函数中,您需要订阅标签的TextChanged
事件
private void HandleLabelTextChanged(object sender, EventArgs e)
{
// we'll explain this in a minute
this.OnLabelsTextChanged(EventArgs.Empty);
}
myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;
现在来看handleLabelTextChanged
方法。我们可以直接提出标签textchanged
;然而,.NET framework设计指南指出,最好创建一个OnEventName
受保护的虚拟方法来为我们引发事件。这样,继承类就可以通过重写OnEventName
方法来“处理”事件,结果表明,该方法的性能比订阅事件要好一些。即使您认为您永远不会覆盖OnEventName
方法,但还是要养成这样做的习惯,因为它简化了事件引发过程
以下是我们的OnLabelsTextChanged
:
protected virtual void OnLabelsTextChanged(EventArgs e)
{
EventHandler handler = this.LabelsTextChanged;
if (handler != null)
{
handler(this, e);
}
}
我们必须检查null,因为没有订阅者的事件是null。如果我们试图引发一个null事件,我们将得到一个NullReferenceException
。请注意,在检查事件的EventHandler
是否为null并引发事件之前,我们将其复制到一个局部变量。如果我们改为这样做:
public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}
_myLabel.TextChanged+=LabelTextChanged;
if (this.LabelsTextChanged != null)
{
this.LabelsTextChanged(this, e);
}
在空性检查和事件引发之间会有一个竞争条件。如果事件的订阅者恰好在我们引发事件之前取消了订阅,但在我们检查null之后,就会抛出异常。您通常不会遇到此问题,但最好养成以安全方式编写的习惯
编辑:以下是如何更改公共事件事件处理程序标签的文本代码>行应放置在:
namespace YourNamespace
{
class MyUserControl : UserControl
{
// it needs to be here:
public event EventHandler LabelsTextChanged;
...
}
}
是关于事件设计的框架设计指南供进一步阅读。编译错误,第二行写着:“预期的类、委托、枚举、接口或结构”,它似乎与“事件
这两行需要在类声明中
public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;
您必须在命名空间
中声明事件
和委托
。请尝试将代码置于类
范围内。它将正常运行。有一种非常简单的方法可以做到这一点
在UserControl窗体上:
将属性更改为public以访问所有位置
在使用UserControl的主窗体上:
.5:在使用
区域中,添加使用userControl1=UserControl.userControl1
1.将“Laod”事件添加到用户控件:
this.userControl1.Load += new System.EventHandler(this.userControl1_Load);
2.在userControl1_加载中:
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.在标签1_文本中更改:
private void label1_TextChanged(object sender, EventArgs e)
{
//do whatever you want
}
您使用的是Winforms还是WPF?我不知道,我使用的是UserControl,但不是WPFW为什么使用“if(TextOfLabelChanged!=null)”?它有一个编译错误,wihch说:“预期的类、委托、枚举、接口或结构“一开始line@saeed:我们必须检查null,因为没有订阅服务器的事件为null。如果我们试图引发一个空事件,我们会得到一个NullReferenceException
.tnx,那么编译错误呢?它有一个编译错误,wihch说:“预期的类、委托、枚举、接口或结构”在第二行,它似乎与“事件”有问题。你的想法也有同样的问题,编译器说:
第一行的“预期类、委托、枚举、接口或结构”有问题event@saeed:您将公共事件事件处理程序标签放置在何处更改;
?它必须位于类内部(而不是方法内部或类定义外部)。@ZachJohnson非常有用!这是“继承内容所需的关键字,或者在这种情况下是可选的?您可以缩短对nullthis.ElementChanged?.Invoke(this,e)的检查时间代码>