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);
}
}
}
现在您可以将它添加到任何页面并绑定 Text 、Command 或 CommandParameter在代码后面 .
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<local:MyControlTemplate ButtonText="{Binding ButtonText}" ButtonCommand="{Binding ClickCommand}" CommandParameter="test" />
</StackLayout>
我有一个 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);
}
}
}
现在您可以将它添加到任何页面并绑定 Text 、Command 或 CommandParameter在代码后面 .
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<local:MyControlTemplate ButtonText="{Binding ButtonText}" ButtonCommand="{Binding ClickCommand}" CommandParameter="test" />
</StackLayout>