在 ReactiveUI WPF 中单击启用和禁用按钮
Enable and disable buttons on click in ReactiveUI WPF
在响应式 UI 中,BindCommand
可以将一些控件绑定到视图模型的 属性 或方法,例如ViewModel
中的方法将在单击 XAML
中的某个按钮时执行。
https://www.reactiveui.net/docs/handbook/commands/binding-commands
如何在单击某些按钮时禁用或启用一组按钮?
根据文档,BindCommand
应该有第三个参数可以接受一些函数,但找不到示例。
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(() => {});
}
ReactiveCommand.Create
接受一个 IObservable<bool>
来确定 CanExecute
的值是否为:
Start = ReactiveCommand.Create(() => { });
Stop = ReactiveCommand.Create(() => { }, Start.Select(_ => true));
Pause = ReactiveCommand.Create(() => { }, Start.Select(_ => true));
考虑到包括我在内的 3 个人投票赞成在 View Model 中创建相关属性并在 XAML 中绑定它们,我先这样做了。
查看模型
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 和视图模型之间的硬编码绑定。
What are the distinctions between the various WhenAny methods in Reactive UI
使用 WhenAnyObservable
我可以订阅选定的命令并从 code-behind 修改 XAML,而无需在视图模型中创建一堆不必要的属性
this
.BindCommand(ViewModel, vm => vm.StartCommand, view => view.StartButton)
.WhenAnyObservable(o => o.ViewModel.StartCommand)
.Subscribe(o =>
{
StartButton.IsEnabled = false;
StopButton.IsEnabled = true;
})
.DisposeWith(container);
完成。
在响应式 UI 中,BindCommand
可以将一些控件绑定到视图模型的 属性 或方法,例如ViewModel
中的方法将在单击 XAML
中的某个按钮时执行。
https://www.reactiveui.net/docs/handbook/commands/binding-commands
如何在单击某些按钮时禁用或启用一组按钮?
根据文档,BindCommand
应该有第三个参数可以接受一些函数,但找不到示例。
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(() => {});
}
ReactiveCommand.Create
接受一个 IObservable<bool>
来确定 CanExecute
的值是否为:
Start = ReactiveCommand.Create(() => { });
Stop = ReactiveCommand.Create(() => { }, Start.Select(_ => true));
Pause = ReactiveCommand.Create(() => { }, Start.Select(_ => true));
考虑到包括我在内的 3 个人投票赞成在 View Model 中创建相关属性并在 XAML 中绑定它们,我先这样做了。
查看模型
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 和视图模型之间的硬编码绑定。
What are the distinctions between the various WhenAny methods in Reactive UI
使用 WhenAnyObservable
我可以订阅选定的命令并从 code-behind 修改 XAML,而无需在视图模型中创建一堆不必要的属性
this
.BindCommand(ViewModel, vm => vm.StartCommand, view => view.StartButton)
.WhenAnyObservable(o => o.ViewModel.StartCommand)
.Subscribe(o =>
{
StartButton.IsEnabled = false;
StopButton.IsEnabled = true;
})
.DisposeWith(container);
完成。