0

I'm trying to implement a method for automatic stretching of the last column. I created new class FancyDataGrid and defined a DependencyProperty called StretchLastColumnProperty. When it's true, following method gets triggered by LayoutUpdated event:

    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);
            }
        }
    }

While this method works for small DataGrid, it doesn't work well if this grid is high enough to have a vertical scrollbar. In this case last column becomes too wide, and the difference is more than just scrollbar width.

What is wrong with my method? How can I adjust last column width, taking scrollbar width into account?

EDIT: Setting last column width to asterisk only works initially. Once column has been resized, its width will not be adjusted anymore.

Arli Chokoev
  • 521
  • 6
  • 22
  • Does this answer your question? [How to make the last column in WPF datagrid take all the left space, always?](https://stackoverflow.com/questions/4389630/how-to-make-the-last-column-in-wpf-datagrid-take-all-the-left-space-always) – Sinatr Oct 20 '20 at 11:10
  • @Sinatr as per OP, this question is unanswered as well – Arli Chokoev Oct 20 '20 at 11:18
  • What you mean? It has 5 answers. – Sinatr Oct 20 '20 at 11:22
  • Original post: "I marked one of the answers as solution, but actually it is not a solution due to WPF design..." All answers are to set the width to the asterisk, which only works for the first time, until this column gets resized. – Arli Chokoev Oct 20 '20 at 11:30
  • *"until this column gets resized"* - can you provide more details on this? Why do you allow to resize columns? What should actually happens if user resize last column? Or other columns? – Sinatr Oct 20 '20 at 14:55
  • The columns might be different in width due to their content, but I want the last column to stretch always, when the sum of columns' widths is less than this of the grid. I mean, when you resize the column so, that the last column goes out of viewport, it should stretch again, when it comes back to the viewport and fits in it, with respect to its minimal width. – Arli Chokoev Oct 21 '20 at 06:24

1 Answers1

0

I peeked into the hierarchy of DataGrid templates and noticed, that inner ColumnHeadersPresenter has exactly the width of the viewport (DataGrid width minus left and right borders minus vertical scrollbar width). So using method from this question you can find this element and get its width:

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

and then use it in to calculate the needed width:

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

Note, that if you stretch the left columns, the last column will shrink to its MinWidth before it starts to move right (out of the viewport), making the horizontal scrollbar appear.

Arli Chokoev
  • 521
  • 6
  • 22