当列宽缩小时,WPF DataGrid不会收缩

jjr*_*rdk 5 wpf wpftoolkit wpfdatagrid

我在WPF中使用DataGrid并希望它缩小到只适合其列的宽度.它很适合初始渲染.当我调整列的大小以使其更宽时,网格也会增长.但是如果我调整列的大小以使其再次变窄,我会在列的右侧获得空白区域(我可以看到列标题灰色区域扩展到列之外.

我想让数据网格用列缩小它的宽度,这样我就不会得到右侧的空白区域.我试图调试代码,据我所知,问题出在DataGridCellsPanel中,但我看不到任何地方可以修复宽度测量.

任何帮助,将不胜感激.

Fre*_*lad 3

不久前我就遇到了这个问题,我对此非常恼火,所以我做了一个丑陋的修复。它并不漂亮,但它可以完成工作。首先,只有当 Horizo​​ntal ScrollBar 不可见时这才会出现问题,因此我们需要对它的引用。一旦加载了所有 DataGridColumn(在我的例子中,所有数据都在 Xaml 中,因此 Loaded 事件),就必须运行此代码,并且它不考虑添加/删除 DataGridColumn,但这是一个简单的修复。

<DataGrid Name="c_dataGrid"
          Loaded="c_dataGrid_Loaded"
          ...>
    <DataGrid.Columns>
        <DataGridTextColumn ..."/>
        <DataGridTextColumn ..."/>
        <!-- ... -->
Run Code Online (Sandbox Code Playgroud)

然后,在 Loaded EventHandler 中,我们获取 DataGrid ScrollViewer 并添加一个监听器,以监听 DataGrid 中每个 DataGridColumn 的 ActualWidthProperty 的变化。

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我们根据所有 DataGridColumn 的大小计算 DataGrid 的大小,并添加一个常量 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想出更好的方法,请告诉我:)

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;
}
Run Code Online (Sandbox Code Playgroud)