Растянуть последний столбец DataGrid

Oct 20 2020

Пытаюсь реализовать метод автоматического растягивания последнего столбца. Я создал новый класс FancyDataGridи определил DependencyPropertyвызываемый StretchLastColumnProperty. Если это правда, по LayoutUpdatedсобытию запускается следующий метод :

    private void StretchLastColumnToTheBorder()
    {
        var widthSum = 0d;
        for (int i = 0; i < Columns.Count; i++)
        {
            widthSum += Columns[i].ActualWidth;
            if (i == Columns.Count - 1 && this.ActualWidth > widthSum)
            {
                var newWidth = Math.Floor(Columns[i].ActualWidth + (this.ActualWidth - widthSum)) -
                    (this.BorderThickness.Left + this.BorderThickness.Right);
                Columns[i].Width = new DataGridLength(newWidth, DataGridLengthUnitType.Pixel);
            }
        }
    }

Хотя этот метод работает для небольших DataGrid, он не работает, если эта сетка достаточно высока, чтобы иметь вертикальную полосу прокрутки. В этом случае последний столбец становится слишком широким, и разница больше, чем просто ширина полосы прокрутки.

Что не так с моим методом? Как настроить ширину последнего столбца с учетом ширины полосы прокрутки?

РЕДАКТИРОВАТЬ: установка ширины последнего столбца на звездочку работает только изначально. После изменения размера столбца его ширина больше не будет изменяться.

Ответы

ArliChokoev Oct 21 2020 at 06:39

Я заглянул в иерархию DataGridшаблонов и заметил, что inner ColumnHeadersPresenterимеет точно такую ​​же ширину, как и область просмотра ( DataGridширина минус левая и правая границы минус ширина вертикальной полосы прокрутки). Итак, используя метод из этого вопроса, вы можете найти этот элемент и получить его ширину:

public double? ViewPortWidth 
{ 
    get 
    {
        return FindChild<DataGridColumnHeadersPresenter>(this, "PART_ColumnHeadersPresenter")?.ActualWidth;
    } 
}

а затем используйте его для вычисления необходимой ширины:

private void StretchLastColumnToTheBorder()
{
    if (ViewPortWidth.HasValue)
    {
        var widthSum = 0d;
        for (int i = 0; i < Columns.Count; i++)
        {
            if (i == Columns.Count - 1 && ViewPortWidth > widthSum + Columns[i].MinWidth)
            {
                var newWidth = Math.Floor(ViewPortWidth.Value - widthSum);
                Columns[i].Width = new DataGridLength(newWidth, DataGridLengthUnitType.Pixel);
                return;
            }
            widthSum += Columns[i].ActualWidth;
        }
    }
}

Обратите внимание, что если вы растянете левые столбцы, последний столбец уменьшится до своего размера, MinWidthпрежде чем он начнет перемещаться вправо (за пределы области просмотра), в результате чего появится горизонтальная полоса прокрутки.