Confessions of a .NET Developer!

Auto-fixing height and width of Button in WPF DataGrid

This short post will explain how to automatically fix the height and width of a Button in WPF DataGrid.
The idea is to take the height and width of the cell containing the button. To set a proper margin, we can reduce both the parameters by using a converter.
First the DataGrid:

        <DataGrid VerticalContentAlignment="Center"
                  RowHeight="50" ColumnWidth="*"                  
                  ItemsSource="{Binding Path=Persons}" 
                <DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"/>
                <DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"/>
                <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}"/>
                <DataGridTemplateColumn Header="Select">
                            <Button Content="Select"
                                    Height="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualHeight}"
                                    Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualWidth}"/>

Lets take a close look at the “Select” column. Its a DataGridTemplateColumn with each row having a Select button. The Button’s height and width is provided by its visual container DatGridCell using the RelativeSource Binding.
It will look something like this:
With no converter

But it doesn’t look good, what’s required is to provide margin. Simply giving margin won’t help.
A converter will be required here to reduce the height and width of the button. On further research, I figured out that a combination of converter and margin can solve the issue, but its still quite unclear to me how it works.

Here is the converter that is used:

    class HeightWidthFixerConverter : IValueConverter
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            if (parameter != null && value != null)
                double reduceBy;
                if (double.TryParse(parameter.ToString(), out reduceBy))
                    return (double)value - reduceBy;
            return value;

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            throw new NotImplementedException();


The ConverterParameter will be used to specify how much height or width you want to reduce by.
The CellTemplate for the DataGrid will look something like this:
Here is the resource key for converter:

        <converter:HeightWidthFixerConverter x:Key="heightWidthFixer"/>

And the CellTemplate:

                <DataGridTemplateColumn Header="Select">
                            <Button Content="Select"
                                    Height="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualHeight, Converter={StaticResource heightWidthFixer}, ConverterParameter=10}"
                                    Width="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=ActualWidth, Converter={StaticResource heightWidthFixer}, ConverterParameter=7}"/>

The height and width has been reduced by 10 & 7 respectively.
The DataGrid will look like something like this:

With Converter

With Converter

It looks fine now, properly spaced. Surely this hack is not the finest, so I would like to hear your thoughts and suggestions for improvement. Somehow I feel there must be some better way to do this, until then I shall use this. Thank you for reading and have a nice day!


December 20, 2011 - Posted by | WPF


  1. Grid? Create a 3×3 grid with fixed border columns and rows, and place the button in the middle cell. But I don’t know if it’s faster than using a converter.

    Comment by Mike | June 26, 2012 | Reply

  2. super

    Comment by renjith K | September 11, 2013 | Reply

  3. how to replace the ConverterParameter=7 to something like ConverterParameter={Binding MyProperty}?


    Comment by Manuel | February 27, 2014 | Reply

  4. Hi Manuel,

    You can’t have a binding in ConverterParameter, as this is not a DependencyProperty. if this is a one-time show, you can use a {StaticResource …}. If you need a runtime behaviour, you need to write a custom MultiValueConverter.

    Comment by Mike | March 19, 2014 | Reply

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: