WPF- How to apply LayoutTransform to a specific DataGridColumnHeader

女生的网名这么多〃 提交于 2019-12-11 04:35:15

问题


I have a DataGrid whose ItemsSource is bound to a System.Data.DataTable. This DataTable is filled at runtime with some text columns and some boolean columns. As expected, the text columns are displayed as DataGridTextColumn and the boolean ones are displayed as DataGridCheckBoxColumn. No problem so far. Now I want the column headers of the checkbox columns to be displayed as vertical. So I defined a style like this:

<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>

The problem is -as commented in the code, I don't know what kind of trigger I should use for the style in order to be applied only to the DataGridCheckBoxColumns and not other types of columns. Any ideas?


回答1:


To fulfill both requisites:

  • Timing : Flip Headers after ItemSource is set
  • Filter : The Style should only be applied to CheckBoxColumns

You could resort to Attached Behaviour:

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>

The timing is controlled by a Flip property. Every time Collection is changed, set Flip to false and then to true again. The Columns are iterated and the Headers of the DataGridCheckBoxColumns are flipped. Note the way this is implemented setting Flip to false does nothing, so the Headers aren't flipped back.

EDIT

Just learned about a shorter method, using the AutoGeneratingColumn event:

<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>

Handler in partial class

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");
}



回答2:


I have checked your code, why did you want to use Trigger?

Please check my following code if it's that you want.

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

Best Regards,

Messi



来源:https://stackoverflow.com/questions/39314550/wpf-how-to-apply-layouttransform-to-a-specific-datagridcolumnheader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!