2010-03-18 63 views
2

我有一個TextBox,它聲明式地設置了TextChanged事件。在某些情況下,我希望以編程方式設置此值。在這些情況下,我想禁用TextChanged事件,直到以編程方式完成設置值爲止。然後,當我完成時,我想恢復事件處理程序的行爲。以編程方式使用事件處理程序的C#+

對於一個文本框,我知道我可以通過以下操作實現這一點:

myTextBox.TextChanged -= myTextBox_TextChanged; 
myTextBox.Text = "[Some Value]"; 
myTextBox.TextChanged += myTextBox_TextChanged; 

不過,我想寫這個功能爲可通過多種方法來訪問一個單一的方法。例如,我試圖做如下類似的事情

private void UpdateTextValue(TextBox textBox, string newValue) 
{ 
    object eventHandler = textBox.TextChanged; 
    textBox.TextChanged -= eventHandler; 
    textBox.Text = newValue; 
    textBox.TextChanged += eventHandler; 
} 

不幸的是,這種方法不起作用。它甚至不會編譯。有沒有一種方法可以封裝我正在試圖在上面顯示的方法中完成的功能?如果是這樣,怎麼樣?

謝謝,

回答

3

你基本上不能。事件公開的唯一功能是訂閱和取消訂閱 - 你不能要求一組現有的處理程序。如果現有的處理程序在您的代碼中,您可以設置一些標誌,意思是「忽略此刻引發的任何更改」 - 但無法有效地刪除所有其他處理程序。

3

我認爲喬恩是對的。不過,我認爲你從錯誤的角度來看問題。

在這種情況下,您實際上想要更改TextBox的行爲,我的首選項是子類TextBox,添加一個布爾型標誌FireOnTextChanged,並且只在布爾值爲true時觸發該事件。這樣你就不必擔心加載和/或卸載事件處理程序。

2

您可以創建派生文本框,覆蓋TextChanged事件以捕獲處理程序添加/刪除調用。

public MyTextbox:Textbox 
{ 
    public Event EventHandler TextChanged 
    { 
     add 
     { 
      //set the base 
      //store locally 
     } 
     remove 
     { 
      //remove from base 
      //remove from local store 
     } 
    } 

    public string Text 
    { 
     get 
     { 
      //return the base 
     } 
     set 
     { 
      //remove local handlers from base 
      //set value in base 
      //reassign handlers. 
     } 
    } 
} 
0

MulticastDelegate

我不知道,但我認爲這是可以做到這樣的:

Delegate[] invocationList = TextChanged.GetInvocationList().Clone(); 
    foreach (EventHandler h in invocationList) { 
     try { 
      TextChanged -= h 
     } catch (Exception exception) { 
      Console.WriteLine(exception.Message); 
     } 
    } 
    foreach (EventHandler h in invocationList) { 
     try { 
      TextChanged += h 
     } catch (Exception exception) { 
      Console.WriteLine(exception.Message); 
     } 
    } 

UPDATE

Clone()來自using System.Linq;

相關問題