问题描述
在响应式 UI 中,BindCommand
可以绑定一些控件来查看模型的属性或方法,例如ViewModel
中的方法,该方法将在 XAML
中的某个按钮被点击时执行.
In reactive UI, BindCommand
can bind some control to view model's property or method, e.g. method in ViewModel
that will be executed when some button in XAML
was clicked.
https://www.reactiveui.net/docs/handbook/commands/binding-commands
如何在单击某些按钮时禁用或启用一组按钮?
根据文档,BindCommand
应该有第三个参数可以接受一些函数,但找不到示例.
According to docs, BindCommand
should have 3rd argument that can accept some function, but can't find an example.
XAML
<Button Content="Start" x:Name="StartButton" />
<Button Content="Stop" x:Name="StopButton" IsEnabled="False" />
<Button Content="Pause" x:Name="PauseButton" IsEnabled="False" />
XAML.cs
// How to enable Stop and Pause when Start was clicked?
this.BindCommand(ViewModel, vm => vm.Stop, view => view.StopButton).DisposeWith(container);
this.BindCommand(ViewModel, vm => vm.Start, view => view.StartButton).DisposeWith(container);
this.BindCommand(ViewModel, vm => vm.Pause, view => view.PauseButton).DisposeWith(container);
// In plain WPF I could do modify controls inside OnClick handler
private void OnStartClick(object sender, RoutedEventArgs e)
{
// How can I do this in Reactive UI?
StopButton.IsEnabled = true;
PauseButton.IsEnabled = true;
}
查看模型
public DashboardViewModel(IScreen screen)
{
HostScreen = screen;
// Or how to get access to controls in these event handlers?
Stop = ReactiveCommand.Create(() => {});
Start = ReactiveCommand.Create(() => {});
Pause = ReactiveCommand.Create(() => {});
}
推荐答案
考虑到包括我在内的 3 个人投票赞成在 View Model 中创建相关属性并在 XAML 中绑定它们,我首先这样做了.
Considering that 3 persons, including me, voted for creating relevant properties in View Model and binding them in XAML, I did this first.
查看模型
public ReactiveCommand<Unit, Unit> StopCommand { get; protected set; }
public ReactiveCommand<Unit, Unit> StartCommand { get; protected set; }
public bool StopState { get => _stopState; set => this.RaiseAndSetIfChanged(ref _stopState, value); }
public bool StartState { get => _startState; set => this.RaiseAndSetIfChanged(ref _startState, value); }
StopCommand = ReactiveCommand.Create(() =>
{
StopState = false;
StartState = true;
});
StartCommand = ReactiveCommand.Create(() =>
{
StopState = true;
StartState = false;
});
XAML
<Button Content="Start" IsEnabled="{Binding Path=StartState}" x:Name="StartButton" />
<Button Content="Stop" IsEnabled="{Binding Path=StopState}" x:Name="StopButton" />
这似乎是最 MVVM 的方法,尽管不完全是响应式 UI 方法.然后,我发现这个答案似乎更优雅,并且不需要 XAML 和视图模型之间的硬编码绑定.
That seemed like the most MVVM approach, even though not exactly a Reactive UI approach. Then, I found this answer that seems to be way more elegant and doesn't require hardcoded bindings between XAML and View Model.
有什么区别Reactive UI 中的各种 WhenAny 方法
使用 WhenAnyObservable
我可以订阅选定的命令并从代码隐藏修改 XAML,而无需在视图模型中创建一堆不必要的属性
Using WhenAnyObservable
I can subscribe to selected command and modify XAML from the code-behind, without creating a bunch of unnecessary properties in the View Model
this
.BindCommand(ViewModel, vm => vm.StartCommand, view => view.StartButton)
.WhenAnyObservable(o => o.ViewModel.StartCommand)
.Subscribe(o =>
{
StartButton.IsEnabled = false;
StopButton.IsEnabled = true;
})
.DisposeWith(container);
完成.
这篇关于在 ReactiveUI WPF 中单击启用和禁用按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!