我无法在 AvaloniaUI 项目中击中命令守卫。
我在 Visual Studio 中创建了一个简单的 AvaloniaUI 测试应用程序:
更改 MainWindowView 和 MainWindowViewModel 如下(根据 https://docs.avaloniaui.net/docs/0.10.x/data-binding/binding-to-commands):
using System.Threading.Tasks;
namespace AvaloniaApplication1.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public bool CanClick(string s)
{
return false;
}
public async Task Click(string s)
{
await Task.CompletedTask;
}
}
}
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaApplication1.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication1.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaApplication1">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<Button Command="{Binding Click}" CommandParameter="A">Click me!</Button>
</Window>
单击按钮时,会执行
Click
方法(并传递适当的参数),但 CanClick
永远不会被调用。
这段代码有什么问题/缺少什么?
一种解决方法是移动 viewModel 中的参数,并使用
ReactiveCommand
的静态方法实现命令。
这是一个工作示例:
using ReactiveUI;
using System.Reactive;
using System.Threading.Tasks;
namespace AvaloniaApplication1.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel() {
MyParameter = "A";
ClickCommand = ReactiveCommand.CreateFromTask(Click, this.WhenAnyValue(x => x.MyParameter, selector: x => x.Length > 3));
}
private async Task Click()
{
await Task.CompletedTask;
}
private string _myParameter;
public string MyParameter {
get => _myParameter;
set
{
if (_myParameter != value)
{
_myParameter = value;
this.RaisePropertyChanged(nameof(MyParameter));
}
}
}
public ReactiveCommand<Unit, Unit> ClickCommand { get; }
}
}
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaApplication1.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication1.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaApplication1">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<StackPanel>
<TextBox Text="{Binding MyParameter, Mode=TwoWay}" />
<Button Command="{Binding ClickCommand}">Click me!</Button>
</StackPanel>
</Window>