Since the DataGrid draws its own borders and the vertical scroll bar is a
child control that sits on top of the client area, you'll need to consider
the BorderStyle, RowHeaderWidth, column widths, and vertical scroll bar
width (if present). To retrieve the column widths, the code below assumes
that the DataGrid is using a custom DataGridTableStyle. If this is not the
case then you may need to make some tweaks to the source.
using System.Reflection;
private void AutoSizeDataGridWidth(DataGrid grid)
{
int width = 0;
// Calculate occupied border space.
switch (grid.BorderStyle)
{
case BorderStyle.None:
{
// Do nothing.
break;
}
case BorderStyle.FixedSingle:
{
width += 4;
break;
}
case BorderStyle.Fixed3D:
{
width += (SystemInformation.Border3DSize.Width * 2);
break;
}
}
// Calculate occupied row header space.
if (grid.TableStyles.Count > 0)
{
if (grid.TableStyles[0].RowHeadersVisible)
{
width += grid.RowHeaderWidth;
}
}
else if (grid.RowHeadersVisible)
{
width += grid.RowHeaderWidth;
}
// Calculate occupied column space.
if (grid.TableStyles.Count > 0)
{
foreach (DataGridColumnStyle column in
grid.TableStyles[0].GridColumnStyles)
{
width += column.Width;
}
}
// Calculate occupied vertical scrollbar space.
PropertyInfo propInfo = grid.GetType().GetProperty("VertScrollBar",
BindingFlags.Instance | BindingFlags.NonPublic);
if (propInfo != null)
{
ScrollBar propValue = propInfo.GetValue(grid, null) as ScrollBar;
if (propValue != null)
{
if (propValue.Visible)
{
width += propValue.Width;
}
}
}
grid.Width = width;
}