I had this problem a while ago and was so annoyed that I made an ugly fix. It's ugly, but he does his job. Firstly, this is only a problem when the horizontal ScrollBar is invisible, so we need a link to it. This code will need to be run as soon as all DataGridColumns are loaded (in my case, everything is in Xaml, so the Loaded event), and this does not require adding / removing DataGridColumns, but this is a simple fix.
<DataGrid Name="c_dataGrid"
Loaded="c_dataGrid_Loaded"
...>
<DataGrid.Columns>
<DataGridTextColumn ..."/>
<DataGridTextColumn ..."/>
Then, in the Loaded EventHandler, we get the DataGrid ScrollViewer and add a listener for changes to the ActualWidthProperty of each DataGridColumn in the DataGrid.
private ScrollViewer m_dataGridScrollViewer = null;
private void c_dataGrid_Loaded(object sender, RoutedEventArgs e)
{
m_dataGridScrollViewer = GetVisualChild<ScrollViewer>(c_dataGrid);
DependencyPropertyDescriptor dependencyPropertyDescriptor =
DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
if (dependencyPropertyDescriptor != null)
{
foreach (DataGridColumn column in c_dataGrid.Columns)
{
dependencyPropertyDescriptor.AddValueChanged(column, DataGridColumn_ActualWidthChanged);
}
}
}
DataGrid DataGridColumns 8.0 ( ).
private void DataGridColumn_ActualWidthChanged(object sender, EventArgs e)
{
if (m_dataGridScrollViewer != null)
{
if (m_dataGridScrollViewer.ComputedHorizontalScrollBarVisibility != Visibility.Visible)
{
double dataGridWidth = 8.0;
foreach (DataGridColumn column in c_dataGrid.Columns)
{
dataGridWidth += column.ActualWidth;
}
c_dataGrid.Width = dataGridWidth;
}
else
{
c_dataGrid.Width = double.NaN;
}
}
}
, :)
public static T GetVisualChild<T>(object parent) where T : Visual
{
DependencyObject dependencyObject = parent as DependencyObject;
return InternalGetVisualChild<T>(dependencyObject);
}
private static T InternalGetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}