Пользовательский элемент управления SL: при отмене регистрации события для предотвращения утечки памяти? - PullRequest
1 голос
/ 23 декабря 2011

Я создаю несколько пользовательских элементов управления wp7 silverlight, которые регистрируют некоторые события в дочерних элементах шаблона в OnApplyTemplate ().

Я думаю, что должен отменить их регистрацию, чтобы предотвратить утечку памяти. Но когда? Я попробовал разгрузить событие - это работает, но у меня есть проблема с этим. Сценарий: На Page1 у меня есть свой пользовательский контроль. Затем происходит переход от Страницы 1 к Странице 2, вызывается событие Unloaded моего пользовательского элемента управления. Все идет нормально. Но затем я возвращаюсь назад, события моего пользовательского элемента управления не регистрируются снова, поэтому с этим элементом управления ничего не происходит.

Тогда я должен правильно регистрировать и отменять регистрацию событий, чтобы все работало, как ожидалось, и я не мог создать утечку памяти?

Спасибо за вашу помощь!

Edit:

Вот пример моего метода OnApplyTemplate ():

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

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Я верю, что ты хочешь что-то вроде этого. :)

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

    this.YourEvent -= new RoutedEventHandler(YourEventHandler);
    this.YourEvent += new RoutedEventHandler(YourEventHandler);
    ...
}

UPDATE

Хорошо, вот как я делаю это в моем пользовательском элементе управления.

        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);
        }
0 голосов
/ 23 декабря 2011

Вы создаете новый ItemsControl в _itemsContainer каждый раз, когда вызывается OnApplyTemplate.

Это может быть источником утечки.

Вам нужно каждый раз создавать новый или проверять его на нулевое значение перед его созданием:

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

Если его нужно воссоздать, вам может потребоваться удалить обработчик события:

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