我有一个包含 3 个标签的 UserControl。我想为它添加一个事件,当其中一个标签的文本发生变化时发生。
我正在使用 Visual Studio 2010
最佳答案
首先,您需要在您的类中声明该事件(连同您的方法和构造函数):
public event EventHandler LabelsTextChanged;
然后您需要创建一个方法来处理各个标签的 TextChanged
事件。
private void HandleLabelTextChanged(object sender, EventArgs e)
{
// we'll explain this in a minute
this.OnLabelsTextChanged(EventArgs.Empty);
}
某处,可能是在您控件的构造函数中,您需要订阅标签的 TextChanged
事件。
myLabel1.TextChanged += this.HandleLabelTextChanged;
myLabel2.TextChanged += this.HandleLabelTextChanged;
myLabel3.TextChanged += this.HandleLabelTextChanged;
现在是HandleLabelsTextChanged
方法。我们可以直接引发 LabelsTextChanged
;然而,.NET Framework 设计指南指出,最好的做法是创建一个 OnEventName
protected 虚拟方法来为我们引发事件。这样,继承类就可以通过覆盖 OnEventName
方法来“处理”事件,事实证明这比订阅事件的性能要好一些。即使您认为永远不会重写 OnEventName
方法,无论如何养成这样做的习惯也是个好主意,因为它简化了事件引发过程。
这是我们的 OnLabelsTextChanged
:
protected virtual void OnLabelsTextChanged(EventArgs e)
{
EventHandler handler = this.LabelsTextChanged;
if (handler != null)
{
handler(this, e);
}
}
我们必须检查是否为空,因为没有订阅者的事件为空。如果我们尝试引发 null 事件,我们将得到一个 NullReferenceException
。请注意,我们将事件的 EventHandler
复制到局部变量,然后再检查它是否为 null 并引发事件。如果我们改为这样做:
if (this.LabelsTextChanged != null)
{
this.LabelsTextChanged(this, e);
}
我们会在无效检查和事件引发之间出现竞争条件。如果事件的订阅者恰好在我们引发事件之前但在我们检查为 null 之后自行取消订阅,则会抛出异常。您通常不会遇到此问题,但最好养成以安全方式编写它的习惯。
编辑:public event EventHandler LabelsTextChanged;
行应该如何放置:
namespace YourNamespace
{
class MyUserControl : UserControl
{
// it needs to be here:
public event EventHandler LabelsTextChanged;
...
}
}
Here是关于事件设计的框架设计指南,供进一步阅读。
关于c# - 如何在 C# 中向 UserControl 添加事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3486377/