Search code examples
c#silverlightcustom-controlsobject-lifetime

SL custom control: When unregister event to prevent memory leak?


I'm creating some custom wp7 silverlight custom controls which register some events on template children in OnApplyTemplate().

I think I must unregister these to prevent a memory leak. But when? I'll tried the unloaded event - this works but I have a problem with this. The scenario: On Page1 I have my custom control. Then navigating away from Page1 to Page2 the Unloaded event of my custom control is called. So far so good. But then I navigate back the events of my custom control aren't registered again so nothing happens then using that control.

Then should I register and unregister events correctly that everything works as expected and I can't create a memory leak?

Thanks for your help!

Edit:

Here an example of my OnApplyTemplate() method:

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

    _itemsContainer = GetTemplateChild("PART_Items") as ItemsControl;
    if (_itemsContainer != null)
    {
        // When to detach this event for correctly object lifetime?
        _itemsContainer.Tap += ItemsContainer_Tap;
    }
}

Solution

  • I believe what you want is something like this. :)

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
    
        this.YourEvent -= new RoutedEventHandler(YourEventHandler);
        this.YourEvent += new RoutedEventHandler(YourEventHandler);
        ...
    }
    

    UPDATE

    Okay, this is how I do this in my custom control.

            if (this._resizer != null)
            {
                this._resizer.DragStarted -= new DragStartedEventHandler(Resizer_DragStarted);
                this._resizer.DragCompleted -= new DragCompletedEventHandler(Resizer_DragCompleted);
                this._resizer.MouseMove -= new MouseEventHandler(Resizer_MouseMove);
            }
    
            this._resizer = this.GetTemplateChild("Resizer") as Thumb;
    
            if (this._resizer != null)
            {
                this._resizer.DragStarted += new DragStartedEventHandler(Resizer_DragStarted);
                this._resizer.DragCompleted += new DragCompletedEventHandler(Resizer_DragCompleted);
                this._resizer.MouseMove += new MouseEventHandler(Resizer_MouseMove);
            }