2010-08-15 57 views
23

我有一个UserControl包含3个标签。我想为它添加一个事件,当其中一个标签的文本发生变化时发生。
我使用Visual Studio 2010如何将事件添加到C#中的UserControl?

+0

您正在使用的WinForms或WPF? – 2010-08-15 05:55:32

+0

我不知道,我使用UserControl,但不是WPF – Saeed 2010-08-15 06:22:03

回答

47

首先,您需要在您的类中(旁边的方法和构造函数)声明的事件:

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方法来“处理”事件,这比订阅事件的性能要好一些。即使你认为你永远不会重写方法,但最好养成这样做的习惯,因为它简化了事件提升过程。

这里是我们的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都在活动设计的进一步阅读框架设计指南。

+0

你的想法也有同样的问题,编译器说:
“预期类,委托,枚举,接口或结构”
第一行 它与事件 – Saeed 2010-08-15 06:38:14

+1

@saeed一个问题:你在哪里把'公共事件EventHandler LabelsTextChanged;'?它必须*在你的类中(不在方法内部或类定义之外)。 – 2010-08-15 06:40:15

+0

tnx,解决了... – Saeed 2010-08-15 06:48:02

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

它有一个编译错误,wihch说:“期望的类,委托,枚举,接口或结构”在第二行 它似乎有问题的“事件“ – Saeed 2010-08-15 06:30:15

2

首先,你应该在你的用户控件声明一个事件,例如:

public event EventHandler TextOfLabelChanged; 

,那么你必须打电话回叫绑定到你的活动功能(如果有任何)在runtime.You可以通过处理标签的TextChanged事件这样做:

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

你可以有OBJE自己的EventArgs ct如果你喜欢。

地方在你的代码,你应该结合您的标签TextChanged事件这种方法是这样的:

_myLabel.TextChanged+=LabelTextChanged; 
+0

为什么你使用”if(TextOfLabelChanged!= null)“? – Saeed 2010-08-15 06:21:15

+0

它有一个编译错误,wihch说: “预期的类,委托,枚举,接口或结构” 在第一行 – Saeed 2010-08-15 06:29:38

+1

@saeed:我们必须检查为null,因为没有订阅者的事件为空。如果我们试图提出一个null事件,我们会得到一个'NullReferenceException'。 – 2010-08-15 06:32:03

1

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


这2个不拘一格要在类的声明。

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

您必须声明Namespaceeventdelegate,尝试将class范围内带来的代码,它将会运行得很好。

1

有一个非常简单的方法来做到这一点!

在用户控件形式:

  1. 更改属性的公共访问无处不

主要形式,你在哪里使用用户控件上:

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

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

this.userControl1.Load += new System.EventHandler(this.userControl1_Load); 

2.In的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日label1_TextChanged:

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