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

如何在C++/WinRT、WinUI 3中以编程方式设置DataTemplate?

解决C++/WinRT中XamlReader加载DataTemplate时的x:DataType错误

问题背景

原本通过XAML可以正常实现ListView的ItemTemplate绑定:

<ListView ItemsSource="{x:Bind MainModelView.GetOrders}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:OrderInfo">
            <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <TextBlock Text="{x:Bind OrderAmount, Mode=OneWay}" FontFamily="Consolas" FontSize="12" Margin="4,0,2,4" Foreground="NavajoWhite"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

但尝试用C++/WinRT通过XamlReader加载DataTemplate时,出现错误:The property 'DataType' was not found in type 'DataTemplate',代码如下:

DataTemplate dt = XamlReader::Load(LR"(
    <DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:DataType="Order">
        <TextBlock Text='{x:Bind Amount, Mode=OneWay}' FontFamily="Consolas" FontSize="12"/>
    </DataTemplate> 
)").as<DataTemplate>();

原因分析

x:DataType是XAML编译时专属属性,仅用于给XAML编译器提供类型信息以做绑定检查,运行时的XamlReader解析器并不识别这个属性,因此直接在加载的XAML字符串中使用会报错。同时x:Bind依赖编译时的类型上下文,运行时加载的DataTemplate无法提供该上下文,也无法正常工作。

解决方案

方案1:改用{Binding}并移除x:DataType

使用传统的{Binding}代替{x:Bind},它是运行时绑定,不需要编译时类型信息,修改后的代码:

DataTemplate dt = XamlReader::Load(LR"(
    <DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
        <TextBlock Text='{Binding Amount, Mode=OneWay}' FontFamily="Consolas" FontSize="12"/>
    </DataTemplate> 
)").as<DataTemplate>();

注意:确保Order类的Amount属性实现了INotifyPropertyChanged接口(如果需要属性更新通知),且ListView的数据源项能被Binding正确访问。

方案2:在XAML资源中预定义模板,代码中引用

如果必须使用x:Bind,可以先在XAML文件的资源中定义带x:DataType的DataTemplate,再在C++/WinRT代码中通过资源键获取:

  1. XAML页面资源部分:
<Page.Resources>
    <DataTemplate x:Key="OrderItemTemplate" x:DataType="local:Order">
        <TextBlock Text='{x:Bind Amount, Mode=OneWay}' FontFamily="Consolas" FontSize="12"/>
    </DataTemplate>
</Page.Resources>
  1. C++/WinRT代码中获取模板:
DataTemplate dt = Resources().Lookup(winrt::box_value(L"OrderItemTemplate")).as<DataTemplate>();

这种方式利用了XAML编译时的类型处理,x:DataType能被正确识别,同时模板可以在代码中复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:32:31