繁体   English   中英

DelegateCommand.CanExecute方法行为不正确

[英]DelegateCommand.CanExecute method not behaving correctly

我将控件绑定到DelegateCommand,并且其CanExecute部分无法正常工作。 我正在使用Prism库。 谁能告诉我为什么?

命令声明和实例化:

public PlayerManagementViewModel(DatabaseManager dbManager)
{
    _dbManager = dbManager;
    this.ResetUpToDateStatusCommand = new DelegateCommand(() => this.ResetXpUpToDateStatus());
    this.DeletePlayerCommand = new DelegateCommand(() => this.DeleteSelectedPlayer(), () => SelectedPlayer != null);
    this.RefreshPlayers();
}

public ICommand DeletePlayerCommand { get; private set; }

SelectedPlayer定义:

public Player SelectedPlayer
{
    get { return _selectedPlayer; }
    set
    {
        SetProperty(ref this._selectedPlayer, value);
        this.OnPropertyChanged(() => this.FormattedPlayerStatus);
    }
}

奇怪的是,如果您查看DeletePlayerCommand实例化上方的DeletePlayerCommand行,那行就可以了。 我没有得到任何CanExecute行为,但至少它能起作用。 DeletePlayerCommand ,即使没有断点, DeletePlayerCommand命令也永远不会触发,除非我完全删除了构造函数的CanExecute部分。

谁能向我解释这是为什么还是我做错了什么?

如果CanExecute的功能DeletePlayerCommand() => SelectedPlayer != null ,则必须有一个DelegateCommandBase.RaiseCanExecuteChanged方法打电话时SelectedProperty值改变:

在UI线程上引发CanExecuteChanged,以便每个命令调用者都可以重新查询以检查命令是否可以执行。

适当的UI元素(带有数据绑定命令)是命令调用程序。

总而言之, SelectedPlayer属性的实现应更新如下:

class PlayerManagementViewModel : BindableBase
{
    private Player _selectedPlayer;
    private readonly DelegateCommand _deletePlayerCommand;

    public PlayerManagementViewModel(...)
    {
        _deletePlayerCommand = new DelegateCommand(() => DeleteSelectedPlayer(), () => SelectedPlayer != null);
    }

    public ICommand DeletePlayerCommand
    {
        get { return _deletePlayerCommand; }
    }

    public Player SelectedPlayer
    {
        get { return _selectedPlayer; }
        set
        {
            SetProperty(ref _selectedPlayer, value);
            OnPropertyChanged(() => FormattedPlayerStatus);
            _deletePlayerCommand.RaiseCanExecuteChanged();
        }
    }
}

这是PRISM DelegateCommnd的设计方式。 请参阅ICommand的CanExecuteChanged事件

或者,您可以派生DelegateCommand来克服该限制。 请参考以下代码。

 class DelegateCmdEx : DelegateCommand
{       
    public DelegateCmdEx(Action executeMethod):base(executeMethod)
    {

    }

    public DelegateCmdEx(Action executeMethod, Func<bool> canExecuteMethod)
        : base(executeMethod, canExecuteMethod)
    {

    }
    public override event EventHandler CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM