DataGrid row content vertical alignment
Asked Answered
P

10

65

I have a regular DataGrid from WPF 4.0 RTM, where I put data from a database. In order to make clean & light style of DataGrid I use a tall/high rows and by default DataGrid aligns row content in top vertical position, but I want to set a center vertical alignment.

I already tried to use this property

VerticalAlignment="Center"

in DataGrid options, but it doesn't help me.

Here is an example of XAML-code, describing my DataGrid without center vertical alignment:

<DataGrid x:Name="ContentDataGrid"
          Style="{StaticResource ContentDataGrid}"
          ItemsSource="{Binding}"
          RowEditEnding="ContentDataGrid_RowEditEnding">
    <DataGrid.Columns>
        <DataGridTextColumn Header="UserID"
                            Width="100"
                            IsReadOnly="True"
                            Binding="{Binding Path=userID}" />
        <DataGridTextColumn Header="UserName"
                            Width="100"
                            Binding="{Binding Path=userName}" />
        <DataGridTextColumn Header="UserAccessLevel"
                            Width="100"
                            Binding="{Binding Path=userAccessLevel}" />
        <DataGridTextColumn Header="UserPassword"
                            Width="*"
                            Binding="{Binding Path=userPassword}" />
    </DataGrid.Columns>
</DataGrid>

Result of executing this code:

alt text

As you can see all row content has top vertical align.

What do I have to add in order to get center vertical alignment of each row content?

Palatinate answered 20/10, 2010 at 18:50 Comment(1)
Another approach, using DataGridColumn inheritance: blog.smoura.com/… - allows to simply set VerticalAlignment property on the inherited column - requires inheriting from each used column type, so that's quite a limitation. Maybe somebody will translate it into behaviour?Vimineous
P
129

Complete solution of this issue at MSDN: Vertical alignment of DataGrid row content.

In brief, in style-file set:

<!--body content datagrid cell vertical centering-->
<Style x:Key="Body_Content_DataGrid_Centering"
        TargetType="{x:Type DataGridCell}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter VerticalAlignment="Center" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

In window file:

<DataGrid x:Name="ContentDataGrid"
          Style="{StaticResource ContentDataGrid}"
          CellStyle="{StaticResource Body_Content_DataGrid_Centering}"
          ItemsSource="{Binding}"
          RowEditEnding="ContentDataGrid_RowEditEnding">
    <DataGrid.Columns>
        <DataGridTextColumn Header="UserID"
                            Width="100"
                            IsReadOnly="True"
                            Binding="{Binding Path=userID}" />
        <DataGridTextColumn Header="UserName"
                            Width="100"
                            Binding="{Binding Path=userName}" />
        <DataGridTextColumn Header="UserAccessLevel"
                            Width="100"
                            Binding="{Binding Path=userAccessLevel}" />
        <DataGridTextColumn Header="UserPassword"
                            Width="*"
                            Binding="{Binding Path=userPassword}" />
    </DataGrid.Columns>
</DataGrid>

This will give you a wanted result:

alt text

Palatinate answered 22/10, 2010 at 10:12 Comment(6)
i know this is an old answer. But isn't this a lot of work for simple centering of content?Westphal
Unfortunatly, I didn't find any other simple solution, if you have such, please, share you knowledge.Palatinate
The main reason is because the DataGrid contains DataGridRow who contains DataGridCell who containt Controls. You want these controls be be vertical center. That's what Toucki is doing.Teleutospore
Note that there is also DataGridColumn.CellStyle property. It is useful if one wants to apply Centered Cell Style to the DataGrid but want 1 or 2 columns Stretched (for example DataGridTemplateColumn with custom background color and centered TextBlock) - define new CellStyle with VerticalAlignment Stetched, and assign it to those columns.Vimineous
Nice , I needed HorizontalAlignment="Center" also for center , <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />Rigger
IMO instead of hardcoding the "center" value it might be worthwhile to bind the Cell's VerticalContentAlignment value inside the template VerticalAlignment="{TemplateBinding VerticalContentAlignment}" instead, that way it will start respect it when set later and you can make this the set-once default style in app.xaml and stop worrying about it.Anticholinergic
C
61

To set individual text alignments you can use:

<DataGridTextColumn.ElementStyle>
   <Style TargetType="TextBlock">
       <Setter Property="TextAlignment" Value="Center" />
   </Style>
</DataGridTextColumn.ElementStyle>
Conduce answered 5/12, 2011 at 11:28 Comment(2)
Yes it works (Use VerticalAlignment, since TextAlignment is for Horizontal text positioning), but you'll have to set element Styles for all columns (Checkbox columns and comboboxcolumns will need to have different styles).Vimineous
It like this way, because it does not break the grid lines if you have those enabled.Unthoughtof
E
22

The following code will vertically align the content of a DataGridTextColumn cell:

<DataGridTextColumn.ElementStyle>
    <Style TargetType="TextBlock">
        <Setter Property="VerticalAlignment" Value="Center"></Setter>
    </Style>
</DataGridTextColumn.ElementStyle>

Edit: I've come back to this problem and found the solution below to work better, it will center the contents of all the cells in DataGridTextRows both horizontally and vertically.

<UserControl.Resources>    
    <ResourceDictionary>
        <Style TargetType="DataGridCell">
            <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
            <Setter Property="VerticalAlignment" Value="Stretch"></Setter>
            <Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
            <Setter Property="TextBlock.TextAlignment" Value="Center"></Setter>
            <Setter Property="TextBlock.VerticalAlignment" Value="Center"></Setter>
        </Style>    
    </ResourceDictionary>
</UserControl.Resources>
Encarnalize answered 9/10, 2013 at 15:22 Comment(1)
Does NOT work. Try setting the DataGrid RowHeight=100 to make rows higher than default height. the gridlines will look totally weird. Your first solution (DataGridTextColumn.ElementStyle) works better for me.Smoothtongued
S
20

This one works for me

 <DataGrid.CellStyle>
   <Style TargetType="DataGridCell">              
     <Setter Property="TextBlock.TextAlignment" Value="Center"/>
     <Setter Property="Template">
       <Setter.Value>
         <ControlTemplate TargetType="{x:Type DataGridCell}">
           <Grid Background="{TemplateBinding Background}">
             <ContentPresenter VerticalAlignment="Center"/>
           </Grid>
         </ControlTemplate>
       </Setter.Value>
     </Setter>
   </Style>
</DataGrid.CellStyle>
Sorgo answered 15/8, 2016 at 14:57 Comment(0)
P
16

You could also do without overriding the ControlTemplate:

    <Style TargetType="{x:Type DataGridCell}">
    <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
Picul answered 11/2, 2014 at 19:29 Comment(2)
Don't know why this answer didn't have any votes. It's much simpler than the more complex answers, and works fine!Leesa
This answer is only working when you don't have vertical grid lines. Otherwise the gridlines will get a gap if you set the RowHeight property.Essene
M
5

The attribute value VerticalAlignment="Center" will center the DataGrid within its parent element.

You probably want VerticalContentAlignment.

Merriott answered 20/10, 2010 at 19:20 Comment(0)
R
4

Just if someone might need it as i did..

To only affect a single column you could use the 'ElementStyle' Property:

<DataGrid ItemsSource="{Binding}">
    <DataGrid.Resources>
        <Style x:Key="DataGridVerticalText" TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Header Title" Binding="{Binding}" ElementStyle="{StaticResource DataGridVerticalText}" />
    </DataGrid.Columns>
</DataGrid>
Romulus answered 9/1, 2020 at 11:32 Comment(0)
J
3

Building on Jamier's answer, the following code did the trick for me when using auto-generated columns:

Style VerticalCenterStyle = new Style();

public MainWindow()
{
  // This call is required by the designer.
  InitializeComponent();

  VerticalCenterStyle.Setters.Add(new Setter(VerticalAlignmentProperty, VerticalAlignment.Center));
}

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{   
  if (e.Column is DataGridTextColumn) {
    ((DataGridTextColumn)e.Column).ElementStyle = VerticalCenterStyle;
  }
}
Jonson answered 27/3, 2016 at 19:29 Comment(0)
A
2

This is my simple solution and it just works perfectly

<DataGridTemplateColumn Header="Hello" Width="200">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="World!" TextAlignment="Center" VerticalAlignment="Center"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I set the width to 200 so you can notice the difference.

Augment answered 24/7, 2019 at 19:57 Comment(1)
Simple yes, and does work. And a bit easier to style with a static resource.Maximilian
C
1

For some reason trying to set TextBlock properties on the DataGridCell, or adding a TextBlock style for DataGridCell both end up just setting the cell's margins instead, looking at live visual tree. That sort of works, but also ruins the vertical border lines.

Using a style for cell's internal ContentPresenter does the job though. This seemed to work well for me:

<Style TargetType="DataGrid">
    <Style.Resources>
        <Style TargetType="DataGridCell">
            <Style.Resources>
                <Style TargetType="ContentPresenter">
                    <Setter Property="VerticalAlignment"
                            Value="Center" />
                </Style>
            </Style.Resources>
        </Style>
    </Style.Resources>
</Style>
Centennial answered 25/1, 2024 at 21:59 Comment(1)
Thank you. This works without breaking the gridlines.Married

© 2022 - 2025 — McMap. All rights reserved.