Avalonia:绑定命令 属性 到 UserControl

Avalonia: Binding Command Property to UserControl

所以我使用 Avalonia 创建了一个自定义按钮控件,我们称之为 MyButtonMyButton 是几个控件的集合,包括一个 Avalonia.Controls.Button 看起来像这样 (MyButton.xaml):

<Border xmlns="https://github.com/avaloniaui"
        .....
        x:Class="myProject.myControls.MyButton">
  <Button x:Name="button"
          Background="Transparent"
          ....
          BorderThickness="0">
    <Panel >
      .....
    </Panel>
  </Button>
</Border>

(是的,我的自定义控件继承自 Avalonia.Controls.Border 而不是 Avalonia.Controls.UserControl

我的计划是进一步传递按钮 Command 属性(具有 x:Name="button" 属性的按钮)并使其可通过 MyButton.[=32 访问=]

所以当我想在 MainWindow.xaml 中使用 MyButton 时,我可以执行以下操作:

<Window ... >
   <Design.DataContext>
        <vm:MainWindowViewModel/>
   </Design.DataContext>
   <myControls:MyButton Command="{Binding MyButton_Click}"/>
</Window>

其中视图模型 MainWindowViewModel.cs 如下所示:

public partial class MainWindowViewModel : ViewModelBase
{
    public void MyButton_Click()
    {
         // do stuff...
    }
}

我在 MyButton.xaml.cs 中尝试执行此操作的方法如下:

public class MyButton : Border
{
    private readonly Button button;

    public MyButton()
    {
        InitializeComponent();
        button = this.FindControl<Button>("button");
    }

    private void InitializeComponent()
    {
        AvaloniaXamlLoader.Load(this);
    }

    public static readonly StyledProperty<ICommand> CommandProperty =
        AvaloniaProperty.Register<MyButton, ICommand>(nameof(Command));


    public ICommand Command
    {
        get { return GetValue(CommandProperty); }
        set
        { // this setter is never executed as can be seen when running with debugger attached
            if (button != null) 
            {
                button.Command = value;
                SetValue(CommandProperty, value);
            }
            else
            {
                Debug.WriteLine("MyButton error: unable to set Command: control not initialized!");
            }
        }
    }
}

然而,当 运行 应用程序并单击按钮时,目标方法 MyButton_Click 永远不会执行。附加调试器似乎 MyButton.Command setter 也从未执行过,我认为这是由于不正确的绑定造成的? (在调试控制台上没有绑定错误或与此相关的任何内容)

经过几个小时的反复试验,我找到了一种解决方法,即在 button 元素上使用反射和自定义 OnClick() 事件处理程序。它有效,但有点丑,需要静态目标方法,所以我的问题是:

如何将 UserControl 上的命令正确绑定到主 Window 的 ViewModel 中包含的方法?

另外:我基于反射的方法是否也可行? (我假设 Avalonia 绑定也以某种方式基于反射?)

不要对样式化属性使用 getter 和 setter,当通过绑定、样式或动画更改 属性 时,它们 不会 被调用(对于WPF、UWP 和 Xamarin.Forms)。相反,您需要通过 <Button Command="{Binding $parent[myControls:MyButton]}" />(首选)绑定嵌套 Button 的命令,或者订阅来自静态构造函数的 属性 更改通知,如原始 Button does.

有关依赖属性的更多信息(其工作方式与 Avalonia 中的 StyledProperty 大致相同):https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-properties-overview