如何在C#中向UserControl添加事件?

时间:2010-08-15 05:51:57

标签: c# winforms events user-controls

我有一个包含3个标签的UserControl。我想为它添加一个事件,当其中一个标签的文本发生变化时会发生这种事件 我正在使用Visual Studio 2010

6 个答案:

答案 0 :(得分:52)

首先,您需要在类中声明事件(与方法和构造函数一起):

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框架设计指南说,最好的做法是创建一个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并引发事件。如果我们这样做了:

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是关于事件设计的框架设计指南,供进一步阅读。

答案 1 :(得分:3)

首先,您应该在usercontrol中声明一个事件,例如:

public event EventHandler TextOfLabelChanged;

然后你必须在运行时调用绑定到你的事件(如果有的话)的回调函数。你可以通过处理像这样的标签的TextChanged事件来做到这一点:

public void LabelTextChanged(object sender,EventArgs e)
{
if(TextOfLabelChanged!=null)
TextOfLabelChanged(sender,e);
}

如果您愿意,可以拥有自己的EventArgs对象。

在代码中的某处,您应该将标签TextChanged事件绑定到此方法,如下所示:

_myLabel.TextChanged+=LabelTextChanged;

答案 2 :(得分:1)

编译错误,在第二行显示“预期的类,委托,枚举,接口或结构”,它似乎与“事件...

有问题

这两行需要在类声明中。

public delegate void TextChangedEventHandler(object sender, EventArgs e);
public event TextChangedEventHandler LabelTextChanged;

答案 3 :(得分:1)

有一种非常简单的方法可以做到这一点!

在UserControl表单上:

  1. 将属性更改为public以便随处访问
  2. 在主窗体上,您正在使用UserControl:

    .5:在using区域添加using userControl1=UserControl.userControl1

    1.将'Laod'事件添加到您的UserControl:

    this.userControl1.Load += new System.EventHandler(this.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.在label1_TextChanged:

     private void label1_TextChanged(object sender, EventArgs e)
     {
         //do whatever you want
     }
    

答案 4 :(得分:0)

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);
    }
}

答案 5 :(得分:0)

您必须在event内声明delegateNamespace。尝试将代码置于class范围内。它会运行良好。