WPF- Как применить LayoutTransform к определенному DataGridColumnHeader

У меня есть DataGrid чья ItemsSource связан с System.Data.DataTable, это DataTable заполняется во время выполнения некоторыми текстовыми столбцами и некоторыми логическими столбцами. Как и ожидалось, текстовые столбцы отображаются как DataGridTextColumn а логические значения отображаются как DataGridCheckBoxColumn, Пока проблем нет. Теперь я хочу, чтобы заголовки столбцов флажков отображались как вертикальные. Итак, я определил такой стиль:

<Style x:Key="ColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
    <Style.Triggers>
        <!--<Trigger Property=??? Value=???>
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="270"/>
                </Setter.Value>
            </Setter>
        </Trigger>-->
    </Style.Triggers>
</Style>

Проблема в том, что, как прокомментировано в коде, я не знаю, какой тип триггера мне следует использовать для стиля, чтобы он применялся только к DataGridCheckBoxColumnс, а не другие типы столбцов. Есть идеи?

2 ответа

Решение

Для выполнения обоих требований:

  • Timing: Flip Headers после того, как ItemSource установлен
  • Фильтр: Стиль должен применяться только к CheckBoxColumns

Вы можете прибегнуть к прикрепленному поведению:

DataGridColumnsBehavior.cs

public static class DataGridColumnsBehavior
{
    public static readonly DependencyProperty
        FlipHeaderProperty =
            DependencyProperty.RegisterAttached("FlipHeader",
                typeof(bool), typeof(DataGridColumnsBehavior),
                    new PropertyMetadata(FlipHeaderChanged));

    public static bool GetFlipHeader(DependencyObject obj)
    {
        return (bool)obj.GetValue(FlipHeaderProperty);
    }
    public static void SetFlipHeader(DependencyObject obj, bool value)
    {
        obj.SetValue(FlipHeaderProperty, value);
    }

    private static void FlipHeaderChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs args)
    {
        var grid = d as DataGrid;
        var flip = (bool)grid.GetValue(FlipHeaderProperty);
        if (grid == null
         || grid.Columns.Count == 0
         || flip == false) return;

        foreach (var column in grid.Columns)
        {
            if (column.GetType() == typeof(DataGridCheckBoxColumn))
                column.HeaderStyle = 
                    (Style)grid.FindResource("CheckBoxColumnHeaderStyle");
        }
    }
}

XAML

<DataGrid ItemsSource="{Binding Collection}" 
          funk:DataGridColumnsBehavior.FlipHeader="{Binding Flip}">
    <DataGrid.Resources>
        <Style x:Key="CheckBoxColumnHeaderStyle" 
               TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="270"/>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.Resources>
</DataGrid>

Время контролируется свойством Flip. Каждый раз, когда коллекция изменяется, установите Flip на false, а затем снова на true. Столбцы повторяются, а заголовки объекта DataGridCheckBoxColumns переворачиваются. Обратите внимание, как это реализовано, если установить для параметра Flip значение false, ничего не происходит, чтобы заголовки не переворачивались.

РЕДАКТИРОВАТЬ

Только что узнали о более коротком методе, используя событие AutoGeneratingColumn:

<DataGrid ItemsSource="{Binding Collection}" 
          AutoGeneratingColumn="dataGrid_AutoGeneratingColumn">
    <DataGrid.Resources>
        <Style x:Key="CheckBoxColumnHeaderStyle" 
               TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="270"/>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.Resources>
</DataGrid>

Обработчик в частичном классе

private void dataGrid_AutoGeneratingColumn(object sender,
    DataGridAutoGeneratingColumnEventArgs e)
{
    DataGrid grid = sender as DataGrid;
    // Only DataGridCheckBoxColumns
    if (e.PropertyType == typeof(bool))
        e.Column.HeaderStyle =
            (Style)grid.FindResource("CheckBoxColumnHeaderStyle");
}

Я проверил ваш код, почему вы хотите использовать Trigger?

Пожалуйста, проверьте мой следующий код, если это то, что вы хотите.

<DataGridCheckBoxColumn.ElementStyle>
                <Style TargetType="CheckBox">
                    <Setter Property="VerticalAlignment" Value="Center" />
                </Style>
            </DataGridCheckBoxColumn.ElementStyle>

С уважением,

Месси

Другие вопросы по тегам