【问题标题】:How to pass a command in XAML?如何在 XAML 中传递命令?
【发布时间】:2017-11-24 18:50:12
【问题描述】:

我有一个以 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 中传递命令?

【问题讨论】:

  • 请注意,这种情况与您在问题中的表述方式略有不同。在您的情况下,您想在用户控件中创建一个可绑定属性。

标签: c# xamarin mvvm xamarin.forms


【解决方案1】:

您应该将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); }
}

那么,我不确定,但由于您在 TapGestureRecognizer 中使用 TapCommand,我认为您还需要在 CircleView 上实现 INotificationChanged

【讨论】:

    【解决方案2】:

    您需要通过向 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。

    【讨论】:

      猜你喜欢
      • 2011-12-30
      • 2017-11-08
      • 2021-06-01
      • 2010-09-26
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多