如何在XAML中传递命令?

时间:2017-11-24 10:05:27

标签: c# xamarin mvvm xamarin.forms

我有一个带有ViewModel的页面作为BindingContext:

public Page()
{
    InitializeComponent();

    this.BindingContext = new ViewModel();
}

ViewModel有一个命令:

public class ViewModel : INotifyPropertyChanged
{
    ...
    public ICommand SomeCommand { get; set; }

    public ViewModel()
    {
        SomeCommand = new Command((object data) => {});
    }
    ...
}

在我的Page.xaml中,我使用自定义的View组件,该组件仅用于显示,并且具有单击功能:

<local:CircleView
    Radius="20"
    InnerText="Click me"
    InnerTextSize="15"
    TapCommand="{Binding SomeCommand}"
/>

在我的CircleView.xaml.cs

...
    public ICommand TapCommand { get; set; }
...

在我的CircleView.xaml中:

...
<TapGestureRecognizer
    Command="{Binding Path=TapCommand, Source={x:Reference Name=CircleView}}"
    CommandParameter="{Binding Path=InnerText, Source={x:Reference Name=CircleView}}"
/>
...

当我运行程序时,我收到错误“没有为TapCommand找到属性,可绑定属性或事件,或者不匹配......”。如何在XAML中传递命令?

2 个答案:

答案 0 :(得分:2)

您应该将TapCommand作为依赖项属性添加到用户控件。将其添加到CircleView.xaml.cs并删除之前定义的TapCommand

另请参阅:dependency-properties-overview

//making is a bindab
public static readonly DependencyProperty TapCommandProperty =
    DependencyProperty.Register("TapCommand", typeof(ICommand), typeof(CircleView) 
            /* possible more options here, see metadata overrides in msdn article*/);

public ICommand TapCommand
{
    get { return (ICommand)GetValue(TapCommandProperty); }
    set { SetValue(TapCommandProperty, value); }
}

然后,我不确定,但由于您在TapCommand使用TapGestureRecognizer,我认为您还需要在CircleView上实施INotificationChanged

答案 1 :(得分:1)

您需要通过向CircleView添加可绑定属性来将ViewModel的引用传递给CircleView:

public static BindableProperty ParentBindingContextProperty = 
    BindableProperty.Create(nameof(ParentBindingContext), typeof(object), 
    typeof(CircleView), null);

public object ParentBindingContext
{
    get { return GetValue(ParentBindingContextProperty); }
    set { SetValue(ParentBindingContextProperty, value); }
}

然后你可以在你的xaml中绑定它(注意x:Name必须匹配x:Reference):

<ContentView ... x:Name="Home" ... >
    ...
    <local:CircleView ParentBindingContext="{Binding Source={x:Reference Home}, Path=BindingContext}"/>

最后,将您的点击手势绑定到CircleView中xaml中“父”视图模型中的命令:

    <TapGestureRecognizer BindingContext="{Binding Source={x:Reference CircleView}, Path=ParentBindingContext}" Command="{Binding Path=TapCommand}" CommandParameter="{Binding Path=InnerText, Source={x:Reference Name=CircleView}}" />

您不需要在CircleView中使用TapCommand。