Я имел эту проблему на некоторое время назад, и я получаю так раздражен этим, что я сделал некрасивый исправление для него. это не красиво, но это становится работа. Во-первых, t его проблема только в том случае, когда горизонтальный ScrollBar невидим, поэтому нам нужна ссылка на него. Этот код должен запускаться после загрузки всех DataGridColumns (в моем случае, все в Xaml, так что событие Loaded), и это не требует добавления/удаления DataGridColumns, но это простое исправление.
<DataGrid Name="c_dataGrid"
Loaded="c_dataGrid_Loaded"
...>
<DataGrid.Columns>
<DataGridTextColumn ..."/>
<DataGridTextColumn ..."/>
<!-- ... -->
Тогда в Loaded EventHandler мы получаем DataGrid ScrollViewer и добавить слушателя изменений в ActualWidthProperty каждого DataGridColumn в 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;
}
Это прекрасное решение. Я немного изменил его, чтобы вместо этого установить свойство MaxWidth. Это решает проблему сетки, расширяющейся за пределами ограничений визуального родителя. Вместо этого я преобразовал его в поведение, чтобы лучше его инкапсулировать. – jjrdk
Кроме того, если DataGridColumn_ActualWidthChanged не вызывается, убедитесь, что вы используете Microsoft.Windows.Controls.DataGridColumn, а не System.Windows.Controls.DataGridColumn, когда вы получаете DependencyPropertyDescriptor. – Monsignor