2011-11-01 37 views
1

我正在創建包含多個零件的自定義控件。裏面創建模板,我訂閱了不同的事件,像這樣:何時取消訂閱自定義控件中的事件

public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 

      this.partAreaCode = this.GetTemplateChild(PartAreaCode) as TextBox; 
      this.partExchange = this.GetTemplateChild(PartExchange) as TextBox; 
      this.partSubscriber = this.GetTemplateChild(PartSubscriber) as TextBox; 

      if (this.partAreaCode == null || this.partExchange == null || this.partSubscriber == null) 
      { 
       throw new NullReferenceException("Template part(s) not available"); 
      } 

      this.partAreaCode.KeyDown += this.AreaKeyDown; 
      this.partAreaCode.TextChanged += this.AreaTextChanged; 

      this.partExchange.KeyDown += this.ExchangeKeyDown; 
      this.partExchange.TextChanged += this.ExchangeTextChanged; 

      this.partSubscriber.KeyDown += this.SubscriberKeyDown; 

      // Template might be applied after dependency property set 
      // lets refresh UI in this case 
      this.UIFromValue(); 
     } 

所以,我不知道是否應該從這些事件中,如果是取消 - 在哪裏以及如何?

回答

3

那麼你已經接受了一個答案,你可能能夠逃脫這種方法,但它對我的口味太冒險了。它假定OnApplyTemplate只有一次被調用。雖然您的自定義控件可能會在OnApplyTemplate多次調用時長時間生活。

我在這裏將概述什麼是硬核控制開發人員,爲簡潔起見,我將使用一個TextBox

[TemplatePart(Name = MyControl.PartAreaCode, Type = typeof(TextBox))] 
public partial class MyControl: Control 
{ 
    public MyControl() 
    { 
      DefaultStyleKey = typeof(MyControl); 
    } 

    #region Template Part Names 
    private const string PartAreaCode = "AreaCodeTextBox"; 
    #endregion 

    #region internal TextBox AreaCodeTextBox 

    private TextBox _AreaCodeTextBox; 
    internal TextBox AreaCodeTextBox 
    { 
      get { return _AreaCodeTextBox; } 
      set 
      { 
       if (_AreaCodeTextBox != null) 
       { 
        _AreaCodeTextBox -= AreaCodeTextBox_KeyDown; 
        _AreaCodeTextBox -= AreaCodeTextBox_TextChanged; 
       } 

       _AreaCodeTextBox = value; 

       if (_AreaCodeTextBox != null) 
       { 
        _AreaCodeTextBox += AreaCodeTextBox_KeyDown; 
        _AreaCodeTextBox += AreaCodeTextBox_TextChanged; 
       } 
      } 
    } 

    #endregion 

    public overide void OnApplyTemplate() 
    { 
      base.OnApplyTemplate(); 
      AreaCodeTextBox = GetTemplateChild(PartAreaCode) as TextBox; 
    } 

    #region Part Event Handlers 
    // Your event handlers here 
    #endregion 
} 

是的,我知道這看起來有點小題大做,但代碼是樣板,我們使用地區彙總的東西,周反覆,所以我們可以檢查代碼實際執行一些有趣的事情,而不關心管道。有了這個例子,它很容易推出到多個部分。

+0

太好了。我希望我可以發佈我的代碼,讓有知識的人閱讀它:)這是我的第一個控制 – katit

+0

+1沒有想到這一點。如果您要更改模板,則不想在存儲器中保留未使用的PART元素。 – dowhilefor

2

你不需要。因爲你的PART元素是事件訂閱者的子項。如果你的主控制器收集垃圾,你的PART元素也是如此。 一個簡短的例子。假設你有2個實例A和B ... A保持對B的硬引用。如果B只在A的引用中保存在內存中,並且A獲取垃圾回收,那麼B也是如此。你不需要清除引用在第一。

如果由於某種原因,當你的元素和你的PART子元素一起生活時,你不再需要事件,當然你不得不放棄。

經驗法則:如果事件所有者的壽命長於用戶,則總是取消訂閱事件。

相關問題