【问题标题】:Xamarin Forms - Set BindingContext of a controltemplateXamarin Forms - 设置控件模板的 BindingContext
【发布时间】:2020-04-17 08:01:12
【问题描述】:

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

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

此时:控件模板中的按钮与每个选项卡中定义的属性绑定。但我希望按钮绑定在一个地方。是不是可以专门为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) -->

【问题讨论】:

    标签: mvvm xamarin.forms data-binding controltemplate


    【解决方案1】:

    您可以创建一个自定义控件(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>
    

    【讨论】:

    • 看起来不错,但我不能用控件模板来实现吗?因为我觉得在这个用例中使用自定义控件更好。
    • 这样你需要在每个视图模型中绑定属性。
    • 另外,如果你的项目是基于MVVM的,使用自定义视图会更友好:)
    猜你喜欢
    • 2019-09-02
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2016-12-26
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多