ui什么时候脱离命令?

Mar*_*ius 6 wpf delegatecommand

我真的对这个问题感到头疼.我有一个主窗口打开一个对话框.对话框关闭后,对话框中绑定的命令上的CanExecute方法仍在执行.这在我的应用程序中引起了一些严重的问题.

例:

MainWindow有一个带有点击处理程序的按钮.这是click事件处理程序:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        DialogWindow window = new DialogWindow();
        window.ShowDialog();
    }
Run Code Online (Sandbox Code Playgroud)

在对话框中,我将一个项控件绑定到对话框窗口中的静态资源,列表中的每个项都有一个命令:

<Window.Resources>

    <Collections:ArrayList x:Key="itemsSource">
        <local:ItemViewModel Description="A"></local:ItemViewModel>
        <local:ItemViewModel Description="B"></local:ItemViewModel>
        <local:ItemViewModel Description="C"></local:ItemViewModel>
    </Collections:ArrayList>

    <DataTemplate DataType="{x:Type local:ItemViewModel}">
            <Button Grid.Column="1" Command="{Binding Path=CommandClickMe}" Content="{Binding Path=Description}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
            </Button>
    </DataTemplate>

</Window.Resources>

<Grid>
    <ToolBar ItemsSource="{StaticResource itemsSource}"></ToolBar>
</Grid>
Run Code Online (Sandbox Code Playgroud)

这是viewmodel:

public class ItemViewModel
{
    private RelayWpfCommand<object> _commandClickMe;

    public RelayWpfCommand<object> CommandClickMe
    {
        get
        {
            if (_commandClickMe == null)
                _commandClickMe = new RelayWpfCommand<object>(obj => System.Console.Out.WriteLine("Hei mom"), obj => CanClickMe());

            return _commandClickMe;
        }
    }

    private bool CanClickMe()
    {
        return true;
    }

    public string Description { get; set; }
Run Code Online (Sandbox Code Playgroud)

这是DelegateCommand实现:

public class RelayWpfCommand<T> : ICommand
{
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    private readonly Predicate<T> _canExecute;
    private readonly Action<T> _execute;

    public RelayWpfCommand(Action<T> execute, Predicate<T> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Forces a notification that the CanExecute state has changed
    /// </summary>
    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

    public bool CanExecute(T parameter)
    {
        return _canExecute(parameter);
    }

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

    bool ICommand.CanExecute(object parameter)
    {
        if (!IsParameterValidType(parameter))
            return false;

        return CanExecute((T)parameter);
    }

    void ICommand.Execute(object parameter)
    {
        if (!IsParameterValidType(parameter))
            throw new ArgumentException(string.Format("Parameter must be of type {0}", typeof(T)));

        Execute((T)parameter);
    }

    private static bool IsParameterValidType(object parameter)
    {
        if (parameter != null && !typeof(T).IsAssignableFrom(parameter.GetType()))
            return false;

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我关闭对话框窗口并在viewExodel上的CanExecute(我使用带有弱事件订阅的Prism DelegateCommand)方法中设置断点,我注意到它会触发,尽管对话框已经关闭.为什么在对话框中的按钮和ViewModel上的命令之间的绑定仍然存在?

我正在检查它是否通过关闭窗口执行,稍后在viewmodel中的"CanClickMe"方法中设置断点.它会被执行一段时间,然后突然停止(可能是由于GC).这种非威慑行为导致问题,因为在实际应用中,视图模型可能已被处理掉.

Anv*_*aka 0

我在不同的项目中多次看到这个问题,我不确定这个令人毛骨悚然的错误是否也潜伏在您的应用程序中,但值得检查。

\n\n

WPF 3.5(包括 SP1)中存在一个已知的内存泄漏问题,基本上,如果您绑定到未\xe2\x80\x99t aDependencyProperty或未\xe2\x80\x99t 实现的内容,则基本上可能会遇到该问题INotifyPropertyChanged。这正是您的代码的目的。

\n\n

只需实施INotifyPropertyChangedItemViewModel看看效果如何。希望这可以帮助。

\n