WPF TabControl内嵌ContentControl的DataTemplate不生效问题排查
问题根因
你定义在ContentControl.Resources里的DataTemplate不生效的核心原因是:你没有为该ContentControl指定Content属性值。
TabControl.ContentTemplate的数据上下文本身就是当前选中Tab对应的Channels集合中的元素,但你在模板内部声明的ContentControl没有显式绑定Content="{Binding}",其Content属性默认值为null,没有可供匹配类型的数据源对象,自然无法触发对应DataTemplate的加载,因此内容区域为空。- 当你移除
TabControl.ContentTemplate时,TabControl会使用默认内容展示逻辑:直接将选中的ViewModel对象调用ToString()方法渲染为文本,因此可以看到字符串输出。
解决方案
有两种常用修复方式:
方式1:补充Content绑定
仅需要在现有代码的ContentControl上添加Content="{Binding}"即可,修改后的TabControl代码如下:
<TabControl x:Name="Channel" ItemsSource="{Binding Channels}" DisplayMemberPath="Index"> <TabControl.ContentTemplate> <DataTemplate> <!-- 补充Content绑定,绑定到当前Channel ViewModel对象 --> <ContentControl Content="{Binding}"> <ContentControl.Resources> <DataTemplate DataType="{x:Type app:ChannelAViewModel}"> <local:ChannelAView DataContext="{Binding}"/> </DataTemplate> <DataTemplate DataType="{x:Type app:ChannelBViewModel}"> <local:ChannelBView DataContext="{Binding}"/> </DataTemplate> </ContentControl.Resources> </ContentControl> </DataTemplate> </TabControl.ContentTemplate> </TabControl>
注意:你代码中上层用于展示Device的
ContentControl也存在同样的未绑定Content的问题,也需要补充Content="{Binding}"才能正常加载DeviceAView/DeviceBView。
方式2:向上迁移DataTemplate(更简洁)
你可以直接将Channel相关的DataTemplate放到TabControl.Resources(或更上层的资源字典)中,不需要显式声明ContentTemplate,TabControl会自动根据选中项的类型匹配对应模板:
<TabControl x:Name="Channel" ItemsSource="{Binding Channels}" DisplayMemberPath="Index"> <TabControl.Resources> <DataTemplate DataType="{x:Type app:ChannelAViewModel}"> <local:ChannelAView DataContext="{Binding}"/> </DataTemplate> <DataTemplate DataType="{x:Type app:ChannelBViewModel}"> <local:ChannelBView DataContext="{Binding}"/> </DataTemplate> </TabControl.Resources> </TabControl>
内容的提问来源于stack exchange,提问作者Adi Hershkovitz
相关产品推荐
相关产品推荐

