WPF UserControl事件处理程序内存丢失

时间:2017-07-12 02:09:03

标签: wpf events controls

我有一个引用UserControl的表单

<Label Grid.Row="1" Grid.Column="2" >Item Category</Label>
<PO:ItemCategorySelector Grid.Row="1" Grid.Column="3" x:Name="usrItemCategoryId" SelectedValueChanged="usrItemCategoryId_SelectedValueChanged"
                               IsOptional="True"  Width="250" />

该事件的定义如下:

   #region events
    public delegate void SelectedValueChangedDelegate(object sender, SelectedValueChangedEventArgs e);
    protected event SelectedValueChangedDelegate _SelectedValueChanged;
    public event SelectedValueChangedDelegate SelectedValueChanged
    {
        add
        {
            if (this._SelectedValueChanged == null)
                this._SelectedValueChanged += value;
        }
        remove
        {
            if (this._SelectedValueChanged != null)
                this._SelectedValueChanged -= value;
        }
    }

protected void RaiseSelectedValueChanged(modItemCategory pItemCategory)
{
    if (this._SelectedValueChanged != null)
    {
        var evt = new SelectedValueChangedEventArgs(pItemCategory);
        this._SelectedValueChanged(this, evt);
    }
}

endregion

我在事件的“添加”和“删除”属性上添加了断点。 当表单加载Add属性触发器时。 当我关闭表单时,Remove属性永远不会触发。 这必然导致我发现的内存泄漏。 当然,如果在XAML中定义了一个控件并且它在事件处理程序中链接,它应该负责删除该处理程序吗?如果不是,你会如何设置删除它?

我错过了什么?

1 个答案:

答案 0 :(得分:0)

  

当然,如果在XAML中定义了一个控件并且它在事件处理程序中链接,它应该负责删除该处理程序吗?

不,没有人为您取消订阅事件处理程序。

但只要事件的发布者(ItemCategorySelector)和事件的订阅者(UserControl)具有相同的生命周期,这就不应该成为问题。

ItemCategorySelector实例一旦有UserControl实例就有资格进行垃圾回收。因此,如果您遇到任何内存泄漏,可能不是因为此事件处理程序。

  

如果不是,你会如何着手删除它?

您可以处理Unloaded事件并使用 - =语法删除事件处理程序:

private void usrItemCategoryId_Unloaded(object sender, RoutedEventArgs e)
{
    usrItemCategoryId.SelectedValueChanged -= usrItemCategoryId_SelectedValueChanged;
}