Mike
Mike

Reputation: 14586

DataGrid row content vertical alignment

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?

Upvotes: 65

Views: 101319

Answers (10)

tokky
tokky

Reputation: 31

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>

Upvotes: 3

Mike
Mike

Reputation: 14586

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

Upvotes: 129

Fresch
Fresch

Reputation: 77

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>

Upvotes: 4

Beyondo
Beyondo

Reputation: 3247

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.

Upvotes: 2

Justin Adrias
Justin Adrias

Reputation: 401

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>

Upvotes: 21

dotNET
dotNET

Reputation: 35400

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

Upvotes: 3

mhansen
mhansen

Reputation: 391

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>

Upvotes: 22

usefulBee
usefulBee

Reputation: 9692

You could also do without overriding the ControlTemplate:

    <Style TargetType="{x:Type DataGridCell}">
    <Setter Property="VerticalAlignment" Value="Center" />
    </Style>

Upvotes: 16

jamier
jamier

Reputation: 842

To set individual text alignments you can use:

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

Upvotes: 62

Nick Desjardins
Nick Desjardins

Reputation: 12954

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

You probably want VerticalContentAlignment.

Upvotes: 5

Related Questions