Allunga l'ultima colonna DataGrid

Oct 20 2020

Sto cercando di implementare un metodo per l'allungamento automatico dell'ultima colonna. Ho creato una nuova classe FancyDataGride definito una DependencyPropertychiamata StretchLastColumnProperty. Quando è vero, il seguente metodo viene attivato LayoutUpdateddall'evento:

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

Sebbene questo metodo DataGridfunzioni per i piccoli , non funziona bene se questa griglia è abbastanza alta da avere una barra di scorrimento verticale. In questo caso l'ultima colonna diventa troppo ampia e la differenza è più della semplice larghezza della barra di scorrimento.

Cosa c'è di sbagliato nel mio metodo? Come posso regolare la larghezza dell'ultima colonna, tenendo conto della larghezza della barra di scorrimento?

MODIFICA: L' impostazione della larghezza dell'ultima colonna su asterisco funziona solo inizialmente. Una volta che la colonna è stata ridimensionata, la sua larghezza non verrà più regolata.

Risposte

ArliChokoev Oct 21 2020 at 06:39

Ho sbirciato nella gerarchia dei DataGridmodelli e ho notato che l'interno ColumnHeadersPresenterha esattamente la larghezza del viewport ( DataGridlarghezza meno i bordi sinistro e destro meno la larghezza della barra di scorrimento verticale). Quindi usando il metodo da questa domanda puoi trovare questo elemento e ottenere la sua larghezza:

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

e poi usalo per calcolare la larghezza necessaria:

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

Nota che se allunghi le colonne di sinistra, l'ultima colonna si ridurrà al suo MinWidthprima di iniziare a spostarsi a destra (fuori dalla visualizzazione), facendo apparire la barra di scorrimento orizzontale.