【问题标题】:Button leaks when using ICommand使用 ICommand 时按钮泄漏
【发布时间】:2013-10-16 00:46:13
【问题描述】:

我看到由CanExecuteChanged 事件处理程序引起的内存泄漏。

public class MyCommand : ICommand
{
  #region ICommand Members

  public virtual bool CanExecute(object parameter)
  {
     return true;
  }

  public event EventHandler CanExecuteChanged;

  protected virtual void OnCanExecuteChanged(EventArgs e)
  {
     if (CanExecuteChanged != null)
        CanExecuteChanged(this, e);
  }

  public void Execute(object parameter)
  {

  }

 #endregion
}

当我运行 ANTS 内存分析器时,它显示绑定到按钮的 CanExecuteChanged 事件处理程序在我的视图模型中有一个 effectivevalueentry。我的视图模型没有被垃圾回收。

XAML

<Button x:Uid="_editButton" x:Name="_editButton"
                            Tag="Edit"
                            Margin="1,1,1,1"
                            DockPanel.Dock="Left"
            Command="{Binding   Path=EditCommand}"
     CommandParameter="{Binding Path=SelectedItems, ElementName=SearchResultGrid}"
                            Content="{DynamicResource icoEdit1512Image}"
                            VerticalAlignment="Center"
                            HorizontalAlignment="Left"
                            Visibility="{Binding Path=NewEditDeleteButtonVisibility}"
                            Localization.Attributes="Tag (Text Modifiable)">
                       <Button.Style>
                          <Style x:Uid="Style_2" TargetType="{x:Type Button}"
                                 BasedOn="{StaticResource dataGridToolBarButtonStyle}">
                             <Style.Triggers>
      <DataTrigger x:Uid="DataTrigger_1" Binding="{Binding ElementName=SearchResultGrid, 
                                                               Path=SelectedItem}"
                                             Value="{x:Null}">
                                   <Setter x:Uid="Setter_3" Property="IsEnabled" Value="False" />
                                </DataTrigger>
                             </Style.Triggers>
                          </Style>
                       </Button.Style>
                    </Button>

【问题讨论】:

  • 事件的内存泄漏是订阅者的问题 - 什么订阅了事件?不管它是什么,它都会保持引用的活力
  • 发布您要绑定到此的 XAML。
  • 我已经用 xaml 更新了我的帖子

标签: wpf


【解决方案1】:

如果您只是为 CanExecute 始终返回 true,您可以执行以下操作:

public event EventHandler CanExecuteChanged { add { } remove { } }

那么处理程序一开始就不会被绑定。

当然,当您真正希望能够更改 CanExecute 时,这将不起作用。该案例的解决方案可以在this SO question找到。

【讨论】:

  • 请参阅问题中的OnCanExecuteChanged 以获取执行此操作的代码。虽然您可能应该在检查 null 之前获取处理程序的副本,因为处理程序可能在检查和引发之间变为 null,这会引发异常。
【解决方案2】:

此问题已在 .NET 4.5 中得到解决。请查看 MSDN 上的 CanExecuteChangedEventManager Class 页面了解更多信息。

从链接页面...这个类

提供 WeakEventManager 实现,以便您可以使用“弱事件侦听器”模式为 CanExecuteChanged 事件附加侦听器。

您可以从 MSDN 上的Weak Event Patterns 页面了解有关弱事件模式的更多信息。

【讨论】:

    猜你喜欢
    • 2018-03-05
    • 2023-03-16
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多