Question

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;
    }
}
Was it helpful?

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

OTHER TIPS

You are creating a new ItemsControl in _itemsContainer every time OnApplyTemplate is called.

This could be the source of the leak.

Do you need to create a new one each time or should you be checking for it being null before creating it:

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

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

If it does need to get recreated then you might need to remove the event handler:

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

    if (_itemsContainer != null)
    {
        _itemsContainer.Tap -= ItemsContainer_Tap;
    }

    _itemsContainer = GetTemplateChild("PART_Items") as ItemsControl;
    if (_itemsContainer != null)
    {
        // When to detach this event for correctly object lifetime?
        _itemsContainer.Tap += ItemsContainer_Tap;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top