简而言之,题目说明了一切。对于那些需要更多细节的人,这里是我的问题所在:我需要将一个自定义ControlTemplate应用到我的DataGrid控件中的DataGridColumnHeader元素,但我也需要根据最接近头的单元格数据对它们进行不同的样式设置。但是,当我在一个ContentTemplateSelector元素上同时设置Template和DataGridColumnHeader属性时,不调用设置为ContentTemplateSelector属性值的DataTemplateSelector。注释掉Template属性设置确认是这样的,因为现在将调用DataTemplateSelector元素。
是的,我知道你们喜欢看一些代码,但是我已经把整个DataGrid控件完全模板化成类似于Excel的样子,所以正如你们可以想象的那样,我有太多的代码要在这里显示。但为了取悦你们,我用一个简单得多的例子重新描述了我的问题.让我们先看看XAML:
<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类:
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;
}
}
}在XAML中,我们看到一个DataGrid,只有一个DataGridTemplateColumn和三个字符串值,每行一个,还有一些资源。在Style部分中,DataGridColumnHeader元素有一个Resource,为它设置了最简单的ControlTemplate,它只包括来自默认ControlTemplate的所需的命名部件。
如果按原样运行应用程序,那么它目前不会中断在Debugger.Break()类中的StringDataTemplateSelector方法。这真是出乎意料。如果您现在注释掉Template属性在Style中的设置并再次运行应用程序,那么现在您将看到程序执行现在将在Debugger.Break()方法处中断,就像预期的那样。
进一步信息
在MSDN的 Property页面的备注部分中,它声明:
如果同时设置了
ContentTemplateSelector和ContentTemplate属性,则忽略此属性。
但是,它没有提到Template属性,而且在MSDN上的 Property页面中也没有提到这一点。
此外,我使用一个简单的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元素应用于DataGridColumnHeader对象的方法,但仍然能够在呈现过程中调用DataTemplateSelector类。
发布于 2018-01-29 16:08:42
在控件模板中添加内容演示程序?
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
<ContentPresenter></ContentPresenter>
</Grid>
</ControlTemplate>https://stackoverflow.com/questions/48503840
复制相似问题