2013-10-15 4 views
0

Я вижу утечку памяти, вызванную обработчиком событий CanExecuteChanged.Утечка кнопки при использовании ICommand

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 EventHandler привязан к кнопке имеет в своем ViewModel в 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> 
+0

Утечки памяти с событиями являются проблемой подписчика - что подписывается на мероприятие? Как бы то ни было, он сохраняет ссылку живым – Charleh

+0

Опубликуйте XAML, где вы привязаны к этому. –

+0

Я обновил сообщение с помощью xaml – user2720165

ответ

0

Если вы просто возвращает истину всегда для CanExecute вы можете сделать следующее:

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

Тогда обработчик не будет связан в первую очередь.

Это, конечно же, не сработает, когда вы действительно захотите изменить CanExecute. Решения для этого случая можно найти в this SO question.

+0

Как вы можете повысить CanExecuteChanged вручную? – user2720165

+0

См. 'OnCanExecuteChanged' из вопроса для кода для этого. Хотя вы, вероятно, должны взять копию обработчика, прежде чем проверять значение null, поскольку обработчик может стать нулевым между проверкой и повышением, что вызовет исключение. – Scroog1

0

Эта проблема была рассмотрена в .NET 4.5. Пожалуйста, загляните на страницу CanExecuteChangedEventManager Class на MSDN для получения дополнительной информации об этом.

От связанной страницы ... этот класс

Обеспечивает реализацию WeakEventManager, так что вы можете использовать «слабый слушатель событий» образец для присоединения слушателей к этому событию CanExecuteChanged.

Вы можете узнать больше о слабых шаблонах событий с сайта Weak Event Patterns на MSDN.

Смежные вопросы