You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:14:28