C# Avalonia:将命令属性绑定到UserControl
因此,我使用Avalonia创建了一个自定义按钮控件,我们称之为C# Avalonia:将命令属性绑定到UserControl,c#,wpf,mvvm,data-binding,avaloniaui,C#,Wpf,Mvvm,Data Binding,Avaloniaui,因此,我使用Avalonia创建了一个自定义按钮控件,我们称之为MyButtonMyButton是多个控件的集合,包括一个Avalonia.controls.Button看起来像这样(MyButton.xaml): 其中视图模型MainWindowViewModel.cs如下所示: public partial class MainWindowViewModel : ViewModelBase { public void MyButton_Click() { /
MyButton
MyButton
是多个控件的集合,包括一个Avalonia.controls.Button
看起来像这样(MyButton.xaml
):
其中视图模型MainWindowViewModel.cs
如下所示:
public partial class MainWindowViewModel : ViewModelBase
{
public void MyButton_Click()
{
// do stuff...
}
}
我在MyButton.xaml.cs
中尝试这样做的方式如下:
<Window ... >
<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
<myControls:MyButton Command="{Binding MyButton_Click}"/>
</Window>
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:边框
{
私人只读按钮;
公共MyButton()
{
初始化组件();
button=此.FindControl(“按钮”);
}
私有void InitializeComponent()
{
avalonixamlloader.Load(此);
}
公共静态只读样式属性CommandProperty=
寄存器(nameof(Command));
公共ICommand命令
{
获取{返回GetValue(CommandProperty);}
设置
{//此setter永远不会执行,因为在连接了调试器的情况下运行时可以看到
如果(按钮!=null)
{
按钮。命令=值;
SetValue(CommandProperty,value);
}
其他的
{
WriteLine(“MyButton错误:无法设置命令:控件未初始化!”);
}
}
}
}
但是,当运行应用程序并单击按钮时,永远不会执行目标方法MyButton\u Click
。附加调试器看起来像是MyButton.Command
setter也从未执行过,我想这可能是由于绑定不正确造成的?(调试控制台上没有绑定错误或与此相关的任何内容)
经过几个小时的反复试验,我找到了一个解决方法,使用反射和按钮元素上的自定义OnClick()
Eventhandler。它可以工作,但有点难看,需要一个静态目标方法,所以我的问题是:
如何将UserControl上的命令正确绑定到主窗口的ViewModel中包含的方法?
另外:我的基于反射的方法也可行吗?(我假设Avalonia绑定也以某种方式基于反射?不要对样式化属性使用getter和setter,当通过绑定、样式或动画更改属性时,不会被调用(对于WPF、UWP和Xamarin.Forms也是如此)。相反,您需要通过
(更可取)绑定嵌套按钮的命令,或者像原始的按钮一样从静态构造函数订阅属性更改通知
更多关于依赖属性的信息(其工作方式与Avalonia中的StyledProperty基本相同):我明白了。实际上,我查看了它是如何在原始按钮(您也链接的按钮)的实现中完成的,并最终使用了DirectProperty
,如下所示:公共静态只读DirectProperty CommandProperty=AvaloniProperty.RegisterDirect(nameof(Command),Button=>Button.Command,(Button,Command)=>按钮。命令=命令,enableDataValidation:true)代码>哪个修复了它。由于我对avalonia不太熟悉,我想知道这是否也适用,或者这种方法是否存在我不知道的任何其他缺点?直接属性用于不需要优先价值体系的情况(即,该属性始终具有一个值)。您可以在此处阅读有关直接属性的更多信息:
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!");
}
}
}
}