WPF DataGrid does not decrease when column width decreases

I am using DataGrid in WPF and want it to shrink to fit the width of its columns. It does it well for initial rendering. When I resize a column to make it wider, the grid also grows. But if I resized the column to make it narrower, I get an empty space to the right of my column (and I see that the gray area of ​​the column header is expanding beyond the columns.

I would like the data grid to reduce its width with columns, so I don't get the empty space on the right. I tried to debug the code, and as far as I can see, the problem is in the DataGridCellsPanel, but I don't see any place to fix the width measurement.

Any help would be appreciated.

+5
source share
3 answers

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;
}
+3

. , MaxWidth. , . , .

, .

public class UpdateWidthOnColumnResizedBehavior : Behavior<DataGrid>
{
        private static readonly DependencyPropertyDescriptor Descriptor;

        static UpdateWidthOnColumnResizedBehavior()
        {
            Descriptor = DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.Columns.CollectionChanged += OnColumnsCollectionChanged;

            foreach (var column in AssociatedObject.Columns)
            {
                AddListener(column);
            }
        }

        void OnColumnsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (var column in e.NewItems.OfType<DataGridColumn>())
                    {
                        AddListener(column);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    foreach (var column in e.OldItems.OfType<DataGridColumn>())
                    {
                        RemoveListener(column);
                    }
                    break;
                case  NotifyCollectionChangedAction.Replace:
                    foreach (var column in e.NewItems.OfType<DataGridColumn>())
                    {
                        AddListener(column);
                    }
                    foreach (var column in e.OldItems.OfType<DataGridColumn>())
                    {
                        RemoveListener(column);
                    }
                    break;
            }
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            foreach (var column in AssociatedObject.Columns)
            {
                RemoveListener(column);
            }
        }

        private void AddListener(DataGridColumn column)
        {
            Descriptor.AddValueChanged(column, ResizeGrid);
        }

        private void RemoveListener(DataGridColumn column)
        {
            Descriptor.RemoveValueChanged(column, ResizeGrid);
        }

        private void ResizeGrid(object sender, EventArgs e)
        {
            var columnsWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth);
            AssociatedObject.MaxWidth = columnsWidth + 2;
            AssociatedObject.InvalidateMeasure();
        }
    }

-, , .

+2

, . , / ( , ).

, jjrdk ResizeGrid, . HorizontalAlignment HorizontalContentAlignment : HorizontalAlignment.Stretch.

void ResizeGrid(object sender, EventArgs e) 
    {
         var scroll = ExTreeHelper.FindVisualChild<ScrollViewer>(AssociatedObject);

        if (scroll != null && null != AssociatedObject.Columns && AssociatedObject.Columns.Count > 0)
        {
            var lastColumn = AssociatedObject.Columns.Last();

            double dataGridWidth = AssociatedObject.Columns.Sum(c => c.ActualWidth) + 2.0;

            if (scroll.ComputedHorizontalScrollBarVisibility != Visibility.Visible)
            {
                RemoveListener(lastColumn);

                AssociatedObject.Columns.Last().Width =
                    AssociatedObject.Columns.Last().Width.DisplayValue + scroll.ViewportWidth - dataGridWidth;

                AssociatedObject.Width = dataGridWidth + scroll.ViewportWidth - dataGridWidth;

                AddListener(lastColumn);
            }
            else
            {
                AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch;
                AssociatedObject.HorizontalContentAlignment = HorizontalAlignment.Stretch;

                AssociatedObject.Width = double.NaN;
            }
        }         }  

, , , , .

, , .

-, , ?

Leon

0

All Articles