Не удается установить оба свойства ContentTemplateSelector и Template для DataGridColumnHeader
Короче говоря, название вопроса говорит само за себя. Для тех, кто хочет более подробно, вот суть моей проблемы: мне нужно применить кастом ControlTemplate
к DataGridColumnHeader
элементы в моем DataGrid
контроль, но мне также нужно стилизовать их по-разному, в зависимости от данных ячейки, ближайших к заголовку. Тем не менее, когда я установил оба ContentTemplateSelector
а также Template
свойства на DataGridColumnHeader
элемент, DataTemplateSelector
это установлено как значение ContentTemplateSelector
свойство не называется. Комментируя 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
и три строковых значения, по одному в каждой строке, и некоторые ресурсы. E сть Style
для DataGridColumnHeader
элемент в Resource
раздел, с самым простым ControlTemplate
настроить для него, который включает в себя только необходимые именованные части из по умолчанию ControlTemplate
,
Если вы запустите приложение, как оно есть, то оно в настоящее время не сломается на Debugger.Break()
метод в StringDataTemplateSelector
учебный класс. Это неожиданно Если вы сейчас закомментируйте настройку Template
недвижимость в Style
и снова запустите приложение, тогда вы увидите, что выполнение программы будет прервано на Debugger.Break()
метод, как и ожидалось.
Дополнительная информация:
В разделе "Замечания" ContentControl.ContentTemplateSelector
На странице свойств MSDN говорится, что
Если оба
ContentTemplateSelector
иContentTemplate
свойства устанавливаются, то это свойство игнорируется.
Тем не менее, он не упоминает Template
собственности и там также нет упоминания об этом на Control.Template
Страница свойств на MSDN.
Кроме того, я попробовал эту же настройку, используя простой 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
класс вызывается во время процесса рендеринга.
1 ответ
Добавить предъявителя контента в свой шаблон?
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
<ContentPresenter></ContentPresenter>
</Grid>
</ControlTemplate>