簡體   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