将ContentControl绑定TreeView选中项,按DataType匹配DataTemplate无显示怎么办?
问题描述
将ContentControl绑定到TreeView的选中项,尝试根据DataType匹配对应的DataTemplate展示内容,但无法显示任何内容。代码如下:
<ContentControl Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="2" DataContext="{Binding SelectedItem, ElementName=DataManagerTreeView, Mode=OneWay}"> <ContentControl.Resources> <DataTemplate DataType="{x:Type daq:DAQChartChannel}"> <StackPanel Orientation="Vertical"> <Label>Name</Label> <Label Content="{Binding Name}"></Label> <Label>AxisX</Label> <Label Content="{Binding AxisX}"></Label> <Label>AxisY</Label> <Label Content="{Binding AxisY}"></Label> </StackPanel> </DataTemplate> <DataTemplate DataType="{x:Type daq:DAQChart}"> <StackPanel Orientation="Vertical"> <Label>Name</Label> <Label Content="{Binding Name}"></Label> </StackPanel> </DataTemplate> <DataTemplate DataType="{x:Type daq:DAQChartsCollection}"> <StackPanel Orientation="Vertical"> <Label>Name</Label> <Label Content="{Binding Name}"></Label> </StackPanel> </DataTemplate> </ContentControl.Resources> </ContentControl>
直接在ContentControl中放置单个StackPanel时,可正常显示选中项的Name属性,说明绑定有效。除使用DataTemplateSelector外,是否有其他解决方法?
解决方法
方案1:将DataTemplate移到更高层级资源字典
WPF资源查找会从当前元素向上遍历,ContentControl自身Resources中的DataTemplate可能因选中项是装箱后的object类型,导致类型匹配失败。把DataTemplate放到父容器(如Window/UserControl)或App.xaml的Resources中,扩大资源查找范围,即可正确匹配对应DataType。
方案2:绑定Content而非仅DataContext
当前代码仅设置了DataContext,但ContentControl的模板匹配逻辑是基于Content属性触发的,空Content不会自动匹配DataTemplate。修改为绑定Content属性:
<ContentControl Grid.Column="1" Grid.RowSpan="3" Grid.ColumnSpan="2" Content="{Binding SelectedItem, ElementName=DataManagerTreeView, Mode=OneWay}"> <!-- 保留原DataTemplate资源 --> </ContentControl>
这样ContentControl会根据Content的实际类型自动匹配对应的DataTemplate,这也是直接放置StackPanel能显示的原因——此时Content就是StackPanel,直接渲染。
方案3:通过Style触发器动态切换模板
给每个DataTemplate指定x:Key,然后利用Style的DataTrigger根据绑定对象的类型切换ContentTemplate,无需自定义DataTemplateSelector:
<ContentControl Content="{Binding SelectedItem, ElementName=DataManagerTreeView}"> <ContentControl.Style> <Style TargetType="ContentControl"> <Style.Triggers> <DataTrigger Binding="{Binding}" Value="{x:Type daq:DAQChartChannel}"> <Setter Property="ContentTemplate" Value="{StaticResource DAQChartChannelTemplate}"/> </DataTrigger> <DataTrigger Binding="{Binding}" Value="{x:Type daq:DAQChart}"> <Setter Property="ContentTemplate" Value="{StaticResource DAQChartTemplate}"/> </DataTrigger> <DataTrigger Binding="{Binding}" Value="{x:Type daq:DAQChartsCollection}"> <Setter Property="ContentTemplate" Value="{StaticResource DAQChartsCollectionTemplate}"/> </DataTrigger> </Style.Triggers> </Style> </ContentControl.Style> <ContentControl.Resources> <DataTemplate x:Key="DAQChartChannelTemplate" DataType="{x:Type daq:DAQChartChannel}"> <StackPanel Orientation="Vertical"> <Label>Name</Label> <Label Content="{Binding Name}"></Label> <Label>AxisX</Label> <Label Content="{Binding AxisX}"></Label> <Label>AxisY</Label> <Label Content="{Binding AxisY}"></Label> </StackPanel> </DataTemplate> <DataTemplate x:Key="DAQChartTemplate" DataType="{x:Type daq:DAQChart}"> <StackPanel Orientation="Vertical"> <Label>Name</Label> <Label Content="{Binding Name}"></Label> </StackPanel> </DataTemplate> <DataTemplate x:Key="DAQChartsCollectionTemplate" DataType="{x:Type daq:DAQChartsCollection}"> <StackPanel Orientation="Vertical"> <Label>Name</Label> <Label Content="{Binding Name}"></Label> </StackPanel> </DataTemplate> </ContentControl.Resources> </ContentControl>
内容的提问来源于stack exchange,提问作者ericg67
相关产品推荐
相关产品推荐

