Xamarin.Forms中TemplateBinding失效问题求助
解决Xamarin ControlTemplate绑定问题的完整示例
我懂你这种踩坑的感觉——官方文档的示例有时候太精简,没说清楚细节,导致复制过去就报错。下面给你一个完整的、可直接运行的简短示例,把ControlTemplate绑定模板化控件属性的两种常见场景都覆盖到:绑定控件自身的属性,以及绑定到绑定上下文的属性。
第一步:定义模板化控件
首先我们需要创建一个自定义的ContentView,作为我们的模板化控件,它需要包含可绑定的属性(必须是BindableProperty,普通CLR属性无法用于TemplateBinding)。
MyTemplatedView.xaml
<?xml version="1.0" encoding="UTF-8"?> <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourAppName.MyTemplatedView"> <!-- 默认内容,会被ControlTemplate覆盖 --> <Label Text="默认显示内容" /> </ContentView>
MyTemplatedView.xaml.cs
using Xamarin.Forms; namespace YourAppName { public partial class MyTemplatedView : ContentView { // 定义HeaderText可绑定属性 public static readonly BindableProperty HeaderTextProperty = BindableProperty.Create(nameof(HeaderText), typeof(string), typeof(MyTemplatedView), string.Empty); public string HeaderText { get => (string)GetValue(HeaderTextProperty); set => SetValue(HeaderTextProperty, value); } // 定义FooterText可绑定属性 public static readonly BindableProperty FooterTextProperty = BindableProperty.Create(nameof(FooterText), typeof(string), typeof(MyTemplatedView), string.Empty); public string FooterText { get => (string)GetValue(FooterTextProperty); set => SetValue(FooterTextProperty, value); } public MyTemplatedView() { InitializeComponent(); } } }
第二步:在页面中使用ControlTemplate
接下来在你的页面里定义ControlTemplate,并使用我们的模板化控件,这里会演示两种绑定方式:
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppName" x:Class="YourAppName.MainPage"> <ContentPage.Resources> <!-- 定义ControlTemplate --> <ControlTemplate x:Key="TealTemplate"> <Grid BackgroundColor="Teal" Padding="15" RowDefinitions="Auto,*,Auto"> <!-- 绑定到模板化控件自身的HeaderText属性 --> <Label Text="{TemplateBinding HeaderText}" FontSize="Large" TextColor="White" Grid.Row="0"/> <!-- ContentPresenter:用于显示使用者传入的自定义内容 --> <ContentPresenter Grid.Row="1"/> <!-- 绑定到模板化控件自身的FooterText属性 --> <Label Text="{TemplateBinding FooterText}" FontSize="Small" TextColor="White" Grid.Row="2"/> </Grid> </ControlTemplate> </ContentPage.Resources> <StackLayout Spacing="25" Padding="20"> <!-- 示例1:直接设置控件属性 --> <local:MyTemplatedView ControlTemplate="{StaticResource TealTemplate}" HeaderText="自定义头部标题" FooterText="自定义底部说明"> <!-- 这里的内容会被ContentPresenter显示 --> <Label Text="这是模板内部的自定义内容" TextColor="White" FontSize="Medium"/> </local:MyTemplatedView> <!-- 示例2:绑定到页面的绑定上下文属性 --> <local:MyTemplatedView ControlTemplate="{StaticResource TealTemplate}" HeaderText="{Binding PageHeader}" FooterText="{Binding PageFooter}"> <Label Text="绑定上下文的示例内容" TextColor="White" FontSize="Medium"/> </local:MyTemplatedView> </StackLayout> </ContentPage>
MainPage.xaml.cs
using Xamarin.Forms; namespace YourAppName { public partial class MainPage : ContentPage { // 用于绑定上下文的属性 public string PageHeader { get; set; } = "来自绑定上下文的头部"; public string PageFooter { get; set; } = "来自绑定上下文的底部"; public MainPage() { InitializeComponent(); BindingContext = this; } } }
关键注意事项
- 不要用
Parent.:你之前的代码里写了{TemplateBinding Parent.HeaderText},这是错误的——TemplateBinding默认就是绑定到模板化控件本身,直接写属性名即可。 - 必须用BindableProperty:模板化控件的属性一定要定义为可绑定属性,普通CLR属性无法被TemplateBinding识别。
- ContentPresenter的必要性:如果需要让使用者自定义模板内的部分内容,一定要添加
ContentPresenter,它会承载你在使用控件时传入的子元素。 - 绑定上下文的区别:如果要绑定到外部数据(比如ViewModel),直接用普通的
{Binding}即可,不需要TemplateBinding。
内容的提问来源于stack exchange,提问作者Tobias von Falkenhayn
相关产品推荐
相关产品推荐

