Не удается установить оба свойства 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>
Другие вопросы по тегам