AvaloniaUI:命令守卫未击中

问题描述 投票:0回答:1

我无法在 AvaloniaUI 项目中击中命令守卫。

我在 Visual Studio 中创建了一个简单的 AvaloniaUI 测试应用程序:

enter image description here

更改 MainWindowView 和 MainWindowViewModel 如下(根据 https://docs.avaloniaui.net/docs/0.10.x/data-binding/binding-to-commands):

MainWindowViewModel.cs:

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;
        }
    }
}

MainWindow.axaml

<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
永远不会被调用。

这段代码有什么问题/缺少什么?

avaloniaui
1个回答
0
投票

一种解决方法是移动 viewModel 中的参数,并使用

ReactiveCommand
的静态方法实现命令。

这是一个工作示例:

MainWindowViewModel.cs:

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; }
    }
}

MainWindow.axaml

<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>
© www.soinside.com 2019 - 2024. All rights reserved.