簡體   English   中英

獲取 ICommand 在 WPF 中執行的狀態以更新 xaml 上的文本

[英]Get status of ICommand execute in WPF in order to update text on xaml

我有一個視圖模型,它看起來像:

public sealed class MyViewModel: INotifyPropertyChanged
{
    public bool ShowSuccess 
    {
        get { return _success; } 
        set 
        { 
            _success = value; 
            PropertyChanged?.Invoke( ... );
        } 
    }

    public ICommand TestCommand 
    {
      get
      {
        _test = _test ?? new MyTestCommand();
        return _test;
      }
    }
}

和命令

public sealed class MyTestCommand : ICommand
{
    public bool CanExecute(object parameter)
    {
      return true;
    }

    public void Execute(object parameter)
    {
       // do stuff
    }
}

並在 xaml 中

 <Button Command="{Binding TestCommand}" Content="Test" />

我想在從MyTestCommand執行Execute后更新ShowSuccess屬性。

如何做到這一點?

謝謝

PS:我還是 WPF 新手,剛學了 MVVM 和自定義命令

您可以為此使用DelegateCommand 這有助於您對所有命令使用一個通用類,而不是創建單獨的 Command 類。

public sealed class MyViewModel : INotifyPropertyChanged
{
    private ICommand _test;
    private bool _success;

    public bool ShowSuccess
    {
        get { return _success; }
        set
        {
            _success = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ShowSuccess)));
        }
    }

    public ICommand TestCommand
    {
        get
        {
            _test = _test ?? new DelegateCommand((arg) => ShowSuccess = true);
            return _test;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class DelegateCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public event EventHandler CanExecuteChanged;

    public DelegateCommand(Action<object> execute)
                   : this(execute, null)
    {
    }

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

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

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

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

我強烈建議看看ReactiveUI——基於 Rx 的 UI 框架——你不必使用它的所有功能,比如內置的依賴注入或視圖位置,但它也很酷。 在這種情況下重新發明輪子是不值得的。

它有一個 ICommand 的實現,它不僅支持開箱即用的異步工作,它還允許命令返回內容(非常有用)並在執行時負責禁用按鈕。

它還帶有DynamicData - 解決與集合相關的所有問題。

所以,最基本的樣本是:

TestCommand = ReactiveCommand.CreateFromTask<int>(async paramater  =>{
   var result = await DoStuff(parameter); // ConfigureAwait(false) might be helpful in more complex scenarios

   return result + 5;
}

TestCommand.Log(this) // there is some customization available here
   .Subscribe(x => SomeVmProperty = x;); // this always runs on Dispatcher out of the box

TestCommand.ThrownExceptions.Log(this).Subscribe(ex => HandleError(ex));

this.WhenAnyValue(x => x.SearchText) // every time property changes
   .Throttle(TimeSpan.FromMilliseconds(150)) // wait 150 ms after the last change
   .Select(x => SearchText) 
   .InvokeCommand(Search); // we pass SearchText as a parameter to Search command, error handling is done by subscribing to Search.ThrownExceptions. This will also automatically disable all buttons bound to Search command

我認為更有用的是能夠在后面的 View 代碼中訂閱。

// LoginView.xaml.cs

ViewModel.Login.Where(x => !x.Success).Subscribe(_ =>{
   PasswordBox.Clear();
   PasswordBox.Focus();
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM