简而言之,问题标题说明了一切。对于那些想要更多详细信息的人来说,这是我的问题的关键所在:我需要将自定义ControlTemplate
应用于DataGridColumnHeader
控件中的DataGrid
元素,但我还需要设置样式不同的是,取决于最靠近标题的单元格数据。但是,当我在ContentTemplateSelector
元素上设置Template
和 DataGridColumnHeader
属性时,DataTemplateSelector
被设置为{的值{1}}属性未被调用。注释ContentTemplateSelector
属性设置确认了这种情况,因为现在将调用Template
元素。
是的,我知道你们喜欢看到一些代码,但我完全模仿整个DataTemplateSelector
控件看起来像Excel,所以你可以想象,我有太多的代码要显示在这里。但只是为了取悦你对饥饿的开发者进行编码,我在一个更简单的例子中重现了我的问题......让我们先看看XAML:
DataGrid
现在最简单的<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Local="clr-namespace:WpfApp1"
xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Items>
<System:String>One</System:String>
<System:String>Two</System:String>
<System:String>Three</System:String>
</DataGrid.Items>
<DataGrid.Resources>
<Local:StringDataTemplateSelector x:Key="StringDataTemplateSelector" />
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
<Setter Property="ContentTemplateSelector" Value="{StaticResource StringDataTemplateSelector}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>
</Window>
类:
DataTemplateSelector
在XAML中,我们看到using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1
{
public class StringDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Debugger.Break();
return null;
}
}
}
,只有一个DataGrid
和三个字符串值,每行一个,以及一些资源。 DataGridTemplateColumn
部分中的Style
元素有一个DataGridColumnHeader
,其中设置了最简单的Resource
,只包含默认{ {1}}。
如果按原样运行应用程序,那么它目前不会在ControlTemplate
类中的ControlTemplate
方法中断。这是出乎意料的。如果现在注释掉Debugger.Break()
中StringDataTemplateSelector
属性的设置并再次运行应用程序,那么现在您将看到程序执行现在将按照Template
方法中断,正如预期的那样
更多信息:
在MSDN的ContentControl.ContentTemplateSelector
Property页面的“备注”部分中,它声明了
如果同时设置了
Style
和Debugger.Break()
属性,则忽略此属性。
但是,它不提及ContentTemplateSelector
属性,并且在MSDN上的Control.Template
Property页面上也没有提及此内容。
此外,我使用简单的ContentTemplate
控件尝试了相同的设置,并且可以确认同时设置Template
和Button
属性并不会阻止ContentTemplateSelector
来自被召唤的阶级:
ContentTemplate
所以,我之后的一种方法是将自定义StringDataTemplateSelector
元素应用于<ItemsControl>
<ItemsControl.Resources>
<Local:StringDataTemplateSelector x:Key="StringDataTemplateSelector" />
<Style TargetType="{x:Type Button}">
<Setter Property="ContentTemplateSelector" Value="{StaticResource StringDataTemplateSelector}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Stroke="Red" StrokeThickness="1" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding Height}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<Button Content="One" />
<Button Content="Two" />
<Button Content="Three" />
</ItemsControl>
个对象,但仍然可以在此期间调用ControlTemplate
类渲染过程。
答案 0 :(得分:1)
在controltemplate中添加内容演示者?
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
<ContentPresenter></ContentPresenter>
</Grid>
</ControlTemplate>