ControlTemplate 在运行时不使用 ContentTemplateSelector
ControlTemplate not using ContentTemplateSelector at runtime
我有一个自定义控件 CheckableItemsControl
,我把它放在一起,它看起来很简单,没有自己的依赖属性,只是派生自 ItemsControl
.
根据 Rachel 在这个问题中的回答:How can I overwrite my ListBox's ItemTemplate and still keep the DisplayMemberPath? 我在 Generic.xaml 中想出了以下样式:
<Style x:Key="{x:Type controls:CheckableItemsControl}" TargetType="{x:Type controls:CheckableItemsControl}"
BasedOn="{StaticResource {x:Type ItemsControl}}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{TemplateBinding ContentPresenter.Content}"
ContentTemplateSelector="{TemplateBinding ContentPresenter.ContentTemplateSelector}"
Margin="5" />
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:CheckableItemsControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Grid.Row="0"
Margin="0,0,0,3">
<Button x:Name="PART_SelectAllButton" Content="Select All" Width="60" Margin="5,0,5,0" />
<Button x:Name="PART_InvertButton" Content="Invert" Width="60" Margin="5,0,5,0" />
</StackPanel>
<Border Grid.Row="1" BorderBrush="{x:Static SystemColors.ActiveBorderBrush}" BorderThickness="1">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
并且使用它是这样的:
<controls:CheckableItemsControl ItemsSource="{Binding Reports}" DisplayMemberPath="ReportName" />
现在,这在设计时工作得很好,设计者正确地渲染了项目 ReportName
显示为文本。
但是在运行时,它只是呈现类型名称,就像您期望的那样,没有内容模板。
我不明白为什么这会在运行时失败。
发现原因是这样的:
wpf debug error output System.WIndows.Data Error 25
最终 ContentTemplateSelector
被忽略了,因为我通过使用 DisplayMemberPath
.
隐含地采用了 ContentTemplate
解决方案可能是添加自定义依赖项 属性 以手动提取值。
更多信息:
来自 MSDN 上的 ContentControl.ContentTemplateSelector Property
页面:
If both the ContentTemplateSelector
and the ContentTemplate
properties are set, then this property is ignored.
我有一个自定义控件 CheckableItemsControl
,我把它放在一起,它看起来很简单,没有自己的依赖属性,只是派生自 ItemsControl
.
根据 Rachel 在这个问题中的回答:How can I overwrite my ListBox's ItemTemplate and still keep the DisplayMemberPath? 我在 Generic.xaml 中想出了以下样式:
<Style x:Key="{x:Type controls:CheckableItemsControl}" TargetType="{x:Type controls:CheckableItemsControl}"
BasedOn="{StaticResource {x:Type ItemsControl}}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{TemplateBinding ContentPresenter.Content}"
ContentTemplateSelector="{TemplateBinding ContentPresenter.ContentTemplateSelector}"
Margin="5" />
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:CheckableItemsControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Grid.Row="0"
Margin="0,0,0,3">
<Button x:Name="PART_SelectAllButton" Content="Select All" Width="60" Margin="5,0,5,0" />
<Button x:Name="PART_InvertButton" Content="Invert" Width="60" Margin="5,0,5,0" />
</StackPanel>
<Border Grid.Row="1" BorderBrush="{x:Static SystemColors.ActiveBorderBrush}" BorderThickness="1">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
并且使用它是这样的:
<controls:CheckableItemsControl ItemsSource="{Binding Reports}" DisplayMemberPath="ReportName" />
现在,这在设计时工作得很好,设计者正确地渲染了项目 ReportName
显示为文本。
但是在运行时,它只是呈现类型名称,就像您期望的那样,没有内容模板。
我不明白为什么这会在运行时失败。
发现原因是这样的:
wpf debug error output System.WIndows.Data Error 25
最终 ContentTemplateSelector
被忽略了,因为我通过使用 DisplayMemberPath
.
ContentTemplate
解决方案可能是添加自定义依赖项 属性 以手动提取值。
更多信息:
来自 MSDN 上的 ContentControl.ContentTemplateSelector Property
页面:
If both the
ContentTemplateSelector
and theContentTemplate
properties are set, then this property is ignored.