Create style for TextBlock in DataGridTextColumn
Asked Answered
S

3

15

I want to create a global style that sets the VerticalAlignment to Center for all TextBlock controls inside a DataGrid or inside a DataGridTextColumn.

I don't want to copy the following into every DataGridTextColumn because it feels repetitive.

<DataGridTextColumn Header="Some Property" Binding="{Binding SomeProperty}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

I tried something like the following but it doesn't work because DataGridTextColumn does not inherit from FrameworkElement or FrameworkContentElement. DataGrid itself does but any further wrapping I try leads to errors:

<Style TargetType="DataGridTextColumn">
    <Setter Property="ElementStyle">
        <Setter.Value>
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
        </Setter.Value>
    </Setter>
</Style>
Spindle answered 3/12, 2013 at 13:15 Comment(0)
E
14

You can define a CellStyle as below:

<Style x:Key="DataGridCellStyle" TargetType="DataGridCell">
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And assign it to the DataGrid: CellStyle="{StaticResource DataGridCellStyle}". In this way all your cells will have content centered.

EDIT: The above code is from one of my projects and also contains the code to remove grid lines in the DataGrid. You can get them back by changing Grid to Border in the template. Like this:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridCell}">
            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>
Emblematize answered 3/12, 2013 at 14:37 Comment(5)
Because I want to apply it everywhere I deleted the x:Key attribute. It works now. But it does too much. When I select a row the whole text in the row disappears (Foreground="White"?). Any ideas?Spindle
@Spindle Did you change the Background? By default, when you select a row, the Foreground becomes white and the Background is blue.Emblematize
That was correct before the change. The Foreground turned white and the background stayed white. I removed Background="{TemplateBinding Background}" to test things out and check if I really needed it. I do need it! Now it works! Can you explain what this binding is doing?Spindle
@Spindle You can google for TemplateBinding and there are plenty of articles about it. For the usage here it means the Background value binds to the Background of the element which the template is applied to - the DataGridCell. And the Background of DataGridCell will be set to blue when the row is selected by a trigger. You can use Blend to check the definitions of the triggers in the default style.Emblematize
By the way the style I put above is from my project and it also contains the change to remove grid lines in the DataGrid. You can change the Grid to Border in the template to get them back.Emblematize
C
25

Create a style as a static resource

<UserControl.Resources>
    <Style x:Key="verticalCenter" TargetType="{x:Type TextBlock}">
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>

Then you can assign it to the ElementStyle of the DataGridTextColumn

<DataGridTextColumn ElementStyle="{StaticResource verticalCenter}" />
Cyprio answered 10/2, 2016 at 10:40 Comment(2)
What if I define the resource inside the app.xaml? Am I still able to refer to that in any way?Sebastian
That should work out of the box, see e.g. wpf-tutorial.com/wpf-application/resources for a nice overview of your options.Cyprio
E
14

You can define a CellStyle as below:

<Style x:Key="DataGridCellStyle" TargetType="DataGridCell">
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And assign it to the DataGrid: CellStyle="{StaticResource DataGridCellStyle}". In this way all your cells will have content centered.

EDIT: The above code is from one of my projects and also contains the code to remove grid lines in the DataGrid. You can get them back by changing Grid to Border in the template. Like this:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridCell}">
            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>
Emblematize answered 3/12, 2013 at 14:37 Comment(5)
Because I want to apply it everywhere I deleted the x:Key attribute. It works now. But it does too much. When I select a row the whole text in the row disappears (Foreground="White"?). Any ideas?Spindle
@Spindle Did you change the Background? By default, when you select a row, the Foreground becomes white and the Background is blue.Emblematize
That was correct before the change. The Foreground turned white and the background stayed white. I removed Background="{TemplateBinding Background}" to test things out and check if I really needed it. I do need it! Now it works! Can you explain what this binding is doing?Spindle
@Spindle You can google for TemplateBinding and there are plenty of articles about it. For the usage here it means the Background value binds to the Background of the element which the template is applied to - the DataGridCell. And the Background of DataGridCell will be set to blue when the row is selected by a trigger. You can use Blend to check the definitions of the triggers in the default style.Emblematize
By the way the style I put above is from my project and it also contains the change to remove grid lines in the DataGrid. You can change the Grid to Border in the template to get them back.Emblematize
U
2

Just use the DataGridTemplateColumn:

<DataGridTemplateColumn Width="SizeToCells">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock HorizontalAlignment="Center" Width="100" Height="20"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Uhlan answered 5/8, 2014 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.