2010-08-15 51 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 
} 
相關問題