74

simple question: How can I set a padding on a dataGridCell in WPF? (either one at a time or on all cells, I don't care)

I have tried using the DataGrid.CellStyle property by adding a setter on the DataGridCell.Padding property as well as using the DataGridColumn.CellStyle property in the same way with no effect.

I also tried using the DataGridColumn.ElementStyle property with no more luck.

I'm kind of stuck there, has anyone managed to get a padding applied on a dataGridCell?

NB: I'll add that no, I cannot use transparent borders to do this, since I already use the border properties for something else. I also cannot use the margin property (which seems to work, surprisingly enough) as I use the background property and I don't want any "blank" space between my cells.

mattruma
  • 16,589
  • 32
  • 107
  • 171
David
  • 6,014
  • 4
  • 39
  • 55

5 Answers5

145

The problem is that the Padding isn't transfered to the Border that's in the Template for DataGridCell. You can edit the Template and add the TemplateBinding for Padding

<DataGrid ...>
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Padding" Value="20"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.CellStyle>
    <!--...-->
</DataGrid>
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
  • 4
    ok, I accepted your answer though I found an other way (a bit more of a hack, but easier in my case): Set up the margin property on the cell's content by using the ElementStyle property. Your solution is nicer though. – David Mar 09 '11 at 14:35
  • 2
    @David: Yes, that'll be another way of doing it. Whatever gets the job done :) – Fredrik Hedblad Mar 09 '11 at 14:40
  • 16
    I'll add that this is yet an other thing that makes me think WPF is still looking far from finished, as far as I'm concerned... – David Mar 09 '11 at 14:44
  • Thanks- had me scratching my head for a bit! – RichardOD May 16 '11 at 15:16
  • This helped me with using the ElementStyle property of the columns to add some formatting: http://blogs.msdn.com/b/vinsibal/archive/2008/08/19/wpf-datagrid-stock-and-template-columns.aspx – statikuz Dec 11 '12 at 20:55
  • 2
    @FredrikHedblad how did you know which properties to apply the TemplateBinding to, on the Border? – echo Jan 18 '18 at 05:58
  • 3
    I've filed an issue for the WPF team to make this scenario easier: https://github.com/dotnet/wpf/issues/2874 – Kirill Osenkov Apr 12 '20 at 00:36
33

Here's a cleaner method (my opinion) that combines the approach from David

<Resources>
    <Style x:Key="ColumnElementStyle" TargetType="TextBlock">
        <Setter Property="Margin" Value="5,0,10,0" />
    </Style>
</Resources>

then...

<DataGridTextColumn ElementStyle="{StaticResource ColumnElementStyle}" />
<DataGridTextColumn ElementStyle="{StaticResource ColumnElementStyle}" />

(in my case, my rows are readonly, so no EditingStyle)

Scott Brickey
  • 1,207
  • 12
  • 22
12

Almost 5 years later, since this question seems to still be of use (it is still getting upvotes) and since it has been requested, here is the solution I used (with the ElementStyle) on a TextColumn (but you can do the same for any type of DataGridColumn):

I did it all in code behind:

class MyTextColumn : DataGridTextColumn
{
    public MyTextColumn()
    {
        ElementStyle = new Style(typeof(TextBlock));
        EditingElementStyle = new Style(typeof(TextBox));

        ElementStyle.Setters.Add(new Setter(FrameworkElement.MarginProperty, new Thickness(3)));
        EditingElementStyle.Setters.Add(new Setter(Control.PaddingProperty, new Thickness(0, 1, 0, 1)));
    }
}

But if you want to do it directly in xaml:

<DataGrid.Columns>
    <DataGridTextColumn>
        <DataGridTextColumn.ElementStyle>
            <Style TargetType="TextBlock">
                <Setter Property="Margin" Value="3"/>
            </Style>
        </DataGridTextColumn.ElementStyle>
        <DataGridTextColumn.EditingElementStyle>
            <Style TargetType="TextBox">
                <Setter Property="Padding" Value="0 1 0 1"/>
            </Style>
        </DataGridTextColumn.EditingElementStyle>
    </DataGridTextColumn>
</DataGrid.Columns>
David
  • 6,014
  • 4
  • 39
  • 55
3

You could also try changing

{Binding BindingValue, StringFormat={}{0:#0.0000}}

to

{Binding BindingValue, StringFormat={}{0:#0.0000 }}

Interestingly enough WPF's XAML {0:#0.0000 } will honor this extra space character in the format of the rendered control to move your values off of the edge of your grid columns.

Jacinda
  • 4,932
  • 3
  • 26
  • 37
Jacob
  • 151
  • 1
  • 4
3
<DataGrid.Columns>
      <DataGridTextColumn  MinWidth="100" Header="Changed by"  Width=""  Binding="{Binding Changedby}" IsReadOnly="True"  >
        <DataGridTextColumn.CellStyle>
          <Style TargetType="DataGridCell">
          <Setter Property="BorderThickness" Value="0"/>
          <Setter Property="Background" Value="Transparent" />
         <Setter Property="FrameworkElement.HorizontalAlignment"Value="Center"/>
          </Style>
      </DataGridTextColumn.CellStyle>
    </DataGridTextColumn>

Raj
  • 29
  • 2