[英]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.