Xamarin Forms - 设置控件模板的 BindingContext

Xamarin Forms - Set BindingContext of a controltemplate

我有一个 xamarin 表单应用程序。它在多个选项卡中有一个 tabbedpage。 tabbedpage 和 te 选项卡,它们每个都有自己的视图模型作为绑定上下文。

在app.xaml中我定义了一个controltemplate。我在每个选项卡中都使用此控件模板,因为我希望每个选项卡在页面底部都有一个按钮。

此时:控件模板中的按钮与每个选项卡中定义的 属性 绑定。但我希望按钮绑定在一个地方。难道不能创建一个专门用于 controltemplate 的 viewmodel 并将 controltemplate 中定义的按钮与该 viewmodel 绑定吗?

当前代码:

        <ControlTemplate x:Key="ActivityStatusButton">
            <StackLayout>

                <ContentPresenter>

                </ContentPresenter>

                <StackLayout VerticalOptions="EndAndExpand" HorizontalOptions="Fill" Padding="15">

                    <Button Style="{StaticResource RedBackGroundWithWhiteTextButtonStyle}" Command="{TemplateBinding BindingContext.ClickOnStatusButton, Mode=TwoWay}" Text="{TemplateBinding BindingContext.ok, Mode=TwoWay}"></Button>
                </StackLayout>

            </StackLayout>
        </ControlTemplate>

一个典型的标签:

<ContentPage ...>

<ContentPage.Content>
    <Label Text="hello"></Label>
</ContentPage.Content>

<!--The control template is placed here (the button) -->

您可以创建自定义控件(ContentView 的子类),例如

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"

             x:Name="template"

             x:Class="App24.MyControlTemplate">
  <ContentView.Content>


        <StackLayout VerticalOptions="EndAndExpand" HorizontalOptions="Fill" Padding="15">

            <Button Clicked="Button_Clicked" Command="{Binding Source={x:Reference template},Path=ButtonCommand}" Text="{Binding  Source={x:Reference template},Path=ButtonText}" CommandParameter="{Binding  Source={x:Reference template},Path=CommandParameter}" />
        </StackLayout>

    </ContentView.Content>
</ContentView>
using System;

using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace App24
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MyControlTemplate : ContentView
    {
        public event EventHandler ButtonClick;

        public static readonly BindableProperty ButtonTextProperty =
        BindableProperty.Create("ButtonText", typeof(string), typeof(MyControlTemplate), default(string));

        public string ButtonText
        {
            get => ((string)GetValue(ButtonTextProperty));
            set => SetValue(ButtonTextProperty, value);
        }

        public static readonly BindableProperty ButtonCommandProperty =
        BindableProperty.Create("ButtonCommand", typeof(ICommand), typeof(MyControlTemplate), null, BindingMode.Default, null);


        public ICommand ButtonCommand
        {
            get => (ICommand)GetValue(ButtonCommandProperty);
            set
            {
                SetValue(ButtonCommandProperty, value);

            }
        }

        public static readonly BindableProperty CommandParameterProperty =
            BindableProperty.Create("CommandParameter", typeof(object), typeof(MyControlTemplate), null);

        public object CommandParameter
        {
            get => (object)GetValue(CommandParameterProperty);
            set => SetValue(CommandParameterProperty, value);
        }

        public MyControlTemplate()
        {
            InitializeComponent();

        }



        private void Button_Clicked(object sender, EventArgs e)
        {
            ButtonClick?.Invoke(sender, e);
        }
    }
}

现在您可以将它添加到任何页面并绑定 TextCommandCommandParameter在代码后面 .

<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">

        <local:MyControlTemplate   ButtonText="{Binding ButtonText}" ButtonCommand="{Binding ClickCommand}" CommandParameter="test" />

</StackLayout>