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

不使用XAML通过C#创建Xamarin ControlTemplate的实现示例

Xamarin 纯C#实现ControlTemplate的方案

直接传入Grid实例的写法无法生效,核心原因是ControlTemplate的构造函数不接收已实例化的控件对象,需要传入返回模板根控件的委托(Func),模板每次加载时都会执行这个委托生成独立的控件树实例。

对应XAML结构的基础实现

你给出的Grid为根节点的模板,转成C#的正确写法如下:

// 实例化ControlTemplate
var customControlTemplate = new ControlTemplate(() =>
{
    // 初始化模板根节点Grid
    var rootGrid = new Grid();

    // 在此处添加Grid的内部子元素,逻辑和原XAML中Grid标签内的内容完全一致
    // 示例:添加内容承载器
    var contentPresenter = new ContentPresenter();
    rootGrid.Children.Add(contentPresenter);

    // 必须返回模板的根节点
    return rootGrid;
});

// 将模板赋值给目标控件即可生效,例如给ContentView、ContentPage等控件赋值
myContentView.ControlTemplate = customControlTemplate;

实现要点

  • 模板内所有控件都要放在委托内部实例化,不要在委托外部提前创建。ControlTemplate是可复用的模板定义,每次应用模板时都会执行委托生成全新的控件实例,外部提前实例化会导致控件重复挂载、状态冲突等异常。
  • 如果需要实现XAML中TemplateBinding的绑定效果,C#中通过RelativeBindingSource.TemplatedParent指定绑定源即可,示例:
// 模板内Label绑定宿主控件的自定义属性HeaderText
var headerLabel = new Label();
headerLabel.SetBinding(
    Label.TextProperty, 
    new Binding("HeaderText", source: RelativeBindingSource.TemplatedParent)
);
rootGrid.Children.Add(headerLabel);
  • 委托的返回值必须是模板的根级控件,也就是原XAML里ControlTemplate标签下直接包裹的第一个元素(对应示例中的Grid),否则模板结构解析会出错。

内容的提问来源于stack exchange,提问作者TheRealEddieDean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:54:21