14

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>
g t
  • 7,287
  • 7
  • 50
  • 85
timmkrause
  • 3,367
  • 4
  • 32
  • 59

3 Answers3

24

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}" />
Michael Spranger
  • 485
  • 4
  • 11
  • What if I define the resource inside the `app.xaml`? Am I still able to refer to that in any way? – C4d Oct 07 '16 at 09:35
  • 1
    That should work out of the box, see e.g. http://www.wpf-tutorial.com/wpf-application/resources/ for a nice overview of your options. – Michael Spranger Oct 08 '16 at 12:03
13

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>
Gildor
  • 2,484
  • 23
  • 35
  • 1
    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? – timmkrause Dec 03 '13 at 15:07
  • @timmkrause Did you change the `Background`? By default, when you select a row, the Foreground becomes white and the Background is blue. – Gildor Dec 03 '13 at 15:26
  • 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? – timmkrause Dec 03 '13 at 15:38
  • 1
    @timmkrause 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. – Gildor Dec 03 '13 at 16:01
  • 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. – Gildor Dec 03 '13 at 16:02
2

Just use the DataGridTemplateColumn:

<DataGridTemplateColumn Width="SizeToCells">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock HorizontalAlignment="Center" Width="100" Height="20"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
g t
  • 7,287
  • 7
  • 50
  • 85
Dwsgg
  • 79
  • 1
  • 1