miałem ten problem na jakiś czas z powrotem, a ja się tak zły przez to, że zrobiłem brzydki poprawkę dla niego. to nie jest ładna, ale robi zadanie po pierwsze jego jest tylko problem, gdy poziomy pasek przewijania jest niewidoczny, więc będziemy potrzebować odniesienia do niego. Ten kod będzie musiał zostać uruchomiony po załadowaniu wszystkich DataGridColumns (w moim przypadku wszystkie w Xaml, więc w załadowanym zdarzeniu) i nie bierze pod uwagę dodawania/usuwania DataGridColumns, ale jest to łatwa łatwa.
<DataGrid Name="c_dataGrid"
Loaded="c_dataGrid_Loaded"
...>
<DataGrid.Columns>
<DataGridTextColumn ..."/>
<DataGridTextColumn ..."/>
<!-- ... -->
Następnie w Loaded EventHandler otrzymujemy DataGrid ScrollViewer i dodać detektor zmian w ActualWidthProperty każdego DataGridColumn w 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);
}
}
}
Następnie obliczyć rozmiaru siatki danych z rozmiaru wszystkich DataGridColumns i dodać stałej 8,0 (co jest zwykle różnica).
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;
}
}
}
Jeśli wymyślić lepszy sposób to daj mi znać :)
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;
}
To dobre rozwiązanie. Zmodyfikowałem go nieznacznie, aby zamiast tego ustawić właściwość MaxWidth. To rozwiązuje problem siatki wychodzącej poza ograniczenia wizualnego rodzica. Przekształciłem go również w zachowanie, aby lepiej je enkapsulować. – jjrdk
Ponadto, jeśli DataGridColumn_ActualWidthChanged nie jest wywoływana, upewnij się, że używasz Microsoft.Windows.Controls.DataGridColumn, a nie System.Windows.Controls.DataGridColumn, gdy otrzymujesz DependencyPropertyDescriptor. – Monsignor