如何在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代码中通过资源键获取:
- 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>
- C++/WinRT代码中获取模板:
DataTemplate dt = Resources().Lookup(winrt::box_value(L"OrderItemTemplate")).as<DataTemplate>();
这种方式利用了XAML编译时的类型处理,x:DataType能被正确识别,同时模板可以在代码中复用。
内容的提问来源于stack exchange,提问作者Endt4sk
相关产品推荐
相关产品推荐

