2

假设我有一个需要使用超链接控件呈现的类的属性。超链接将绑定到视图模型上的命令,以便单击它会触发一些操作。像这样的东西:

<Style x:Key="HyperlinkStyle" TargetType="{x:Type igDP:CellValuePresenter}">
   <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}">
                    <Border BorderBrush="{StaticResource DataGridCellOuterBorder}" BorderThickness="1,0,0,0"  >
                        <TextBlock Margin="5">
                                <Hyperlink                                      
                                    Command="{Binding ElementName=dataGrid, Path=DataContext.Commands[GetSolutionSummaryCmd], Mode=OneTime}"
                                    CommandParameter="{Binding Path=(igDP:DataRecord.DataItem), Mode=OneTime}">
                                    <TextBlock Text="{TemplateBinding Value}"/>                                                                      
                                </Hyperlink>                                                                                
                            </TextBlock>
                    </Border>                 
                </ControlTemplate>
            </Setter.Value>
        </Setter>       
    </Style>

如何确保从网格中删除数据项时,dataGrid.DataContext.Command[GetSolutionSummaryCmd]、ICommand 的实现与每个具有超链接列的数据记录之间的绑定被破坏,从而可以对数据项进行垃圾收集?否则,我在这里看到内存泄漏的可能性。

此外,GetSolutionSummaryCmd 是 RelayCommand 的一个实例,实现如下:

public class RelayCommand  : ICommand
{
    readonly protected Predicate<object> _canExecute;
    readonly protected Action<object> _execute;

    public RelayCommand(Predicate<object> canExecute, Action<object> execute)
        : this(canExecute, execute, true)
    {
    }

    public RelayCommand(Predicate<object> canExecute, Action<object> execute, bool isCommandAllowed)
    {
        _canExecute = canExecute;
        _execute = execute;
        IsAllowed = isCommandAllowed;
    }

    public void RaiseCanExecuteChanged()
    {
        if (this.CanExecuteChanged != null)
            this.CanExecuteChanged(this, EventArgs.Empty);
    }

    #region ICommand Members

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

    public event EventHandler CanExecuteChanged;

    public virtual void Execute(object parameter)
    {
        _execute(parameter);
    }    

    #endregion 
}

与此相反,我需要能够提高 CanExecuteChanged。

4

1 回答 1

2

我使用这里的建议来解决这个问题。泄漏肯定是由上述样式中使用的超链接元素引起的。ANTS 探查器通过内存快照之间的 System.Windows.EffectiveValueEntry[] 的正实例计数表明了这一点。当我查看这个类的对象引用图时,总是有一个对链中超链接实例的引用。

基础数据已更改,以便在单击时始终可以执行超链接。这意味着不必引发 ICommand 的 CanExecuteChanged 事件,允许我定义某种 NoReferenceRelayCommand 类,如下所示:

    public class NoReferenceRelayCommand : ICommand
    {
        protected readonly Action<object> _execute;

        public NoReferenceRelayCommand(Action<object> execute)
        {
            Guard.ThrowIfArgumentIsNull(execute);
            _execute = execute;
        }

        #region ICommand Members

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

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

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        #endregion
    }

超过 10 小时的分析解决方案显示 System.Windows.EffectiveValueEntry 的实例数没有增加。

于 2013-01-09T12:09:22.940 回答