DataGridView AutoFit and Fill

85

Mam 3 kolumny w moim DataGridView. To, co próbuję zrobić, to automatyczne dopasowanie pierwszych 2 kolumn do szerokości treści, a trzecia kolumna wypełni pozostałe miejsce.

Czy można to zrobić w WinForms? Ładuję moje dane z EF DataContext, jeśli jest to jakiekolwiek zastosowanie. Dołączyłem obraz, jak to obecnie wygląda.

wprowadź opis obrazu tutaj

James Jeffery
źródło

Odpowiedzi:

168

Musisz skorzystać z DataGridViewColumn.AutoSizeModenieruchomości.

Możesz użyć jednej z tych wartości dla kolumny 0 i 1:

AllCells: szerokość kolumny dostosowuje się do zawartości wszystkich komórek w kolumnie, w tym do komórki nagłówka.
AllCellsExceptHeader: Szerokość kolumny jest dostosowywana do zawartości wszystkich komórek w kolumnie, z wyjątkiem komórki nagłówka.
DisplayedCells: szerokość kolumny jest dostosowywana w celu dopasowania zawartości wszystkich komórek w kolumnie, które są w wierszach aktualnie wyświetlanych na ekranie, w tym komórki nagłówka.
DisplayedCellsExceptHeader: szerokość kolumny jest dostosowywana do zawartości wszystkich komórek w kolumnie, które są w wierszach aktualnie wyświetlanych na ekranie, z wyjątkiem komórki nagłówka.

Następnie użyj wartości Fill dla kolumny 2

Szerokość kolumny jest dostosowywana w taki sposób, aby szerokości wszystkich kolumn dokładnie wypełniały obszar wyświetlania kontrolki ...

this.DataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

Jak zauważyli inni użytkownicy, wartość domyślną można ustawić na datagridviewpoziomie DataGridView.AutoSizeColumnsModewłaściwości.

this.DataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;

możliwe:

this.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;

Ważna uwaga:

Jeśli twoja siatka jest powiązana ze źródłem danych, a kolumny są generowane automatycznie ( AutoGenerateColumnswłaściwość ustawiona na True), musisz użyć DataBindingCompletezdarzenia, aby zastosować styl PO utworzeniu kolumn.


W niektórych scenariuszach (na przykład zmiana wartości komórek według kodu) musiałem wywołać, DataGridView1.AutoResizeColumns();aby odświeżyć siatkę.

Chris
źródło
1
Działa doskonale podczas korzystania ze zdarzenia DataBindingComplete.
James Jeffery,
Nie mogę pojąć, jak wywołać metodę DataBindingComplete po wypełnieniu datagrid
Dan
@Dan DataBindingComplete nie jest metodą , jest to zdarzenie datagridview , na które należy się zapisać. W tej odpowiedzi stackoverflow.com/a/31685874/2387010 podano przykład. Czy to pomaga?
Chris,
Byłoby pomocne, gdyby przykład został wyjaśniony, ale wystarczy. Artykuł MSDN, do którego utworzyłeś łącze w swoim poście, przedstawia go jako metodę, której użyłem jako wzorca, ale nie mogę dowiedzieć się, jak jest wywoływany.
Dan,
1
@ Chris, ta brakująca informacja jest zdecydowanie pomocna, dzięki. Czytam tę książkę i właśnie dotarłem do rozdziału o delegatach i funkcjach lambda, więc mam nadzieję, że wkrótce będzie to miało więcej sensu. Dziękuję Ci!
Dan,
22

To moje ulubione podejście ...

_dataGrid.DataBindingComplete += (o, _) =>
    {
        var dataGridView = o as DataGridView;
        if (dataGridView != null)
        {
           dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
           dataGridView.Columns[dataGridView.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }
    };
AlfredBr
źródło
Jeśli rozmiar kolumny = 0, index out of bound exceptionnapraw to, dzięki !!
TiyebM
14

Po prostu zmień właściwość z właściwości kontroli: AutoSizeColumnsMode:Fill

LUB Według kodu

dataGridView1.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.Fill;

Ahosan Karim Asik
źródło
1
Dziękuję Ci. Szukałem takiego rozwiązania! :)
Alin Ciocan,
4

Nie testowane, ale możesz spróbować. Przetestowane i działające. Mam nadzieję, że można bawić się AutoSizeModez DataGridViewColumaby osiągnąć to, co trzeba.

Spróbuj ustawić

dataGridView1.DataSource = yourdatasource;<--set datasource before you set AutoSizeMode

//Set the following properties after setting datasource
dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

To powinno działać

Sriram Sakthivel
źródło
To nie działa. Ustawiam go, gdy formularz jest inicjowany przed dodaniem źródła danych z DataContext. Czy to może być dlaczego? Nie jestem pewien, gdzie go ustawić, ponieważ dane są ładowane w czasie wykonywania, a kolumny są pobierane z modelu EF.
James Jeffery,
Wygląda na to, ale nie, trzecia linia nie działa, testowałem to 10 minut temu.
King King,
@JamesJeffery Automatycznie wypełniasz kolumny lub ręcznie?
Sriram Sakthivel,
@SriramSakthivel Używam właściwości dataGridView1.DataSource, aby powiązać listę zwróconą z mojego DataContext.
James Jeffery,
0

Spróbuj zrobić,

 AutoSizeColumnMode = Fill;
Aki
źródło
0
public static void Fill(DataGridView dgv2)
   {
        try
        {
            dgv = dgv2;
            foreach (DataGridViewColumn GridCol in dgv.Columns)
            {
                for (int j = 0; j < GridCol.DataGridView.ColumnCount; j++)
                {
                    GridCol.DataGridView.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                    GridCol.DataGridView.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                    GridCol.DataGridView.Columns[j].FillWeight = 1;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
Sójka
źródło
1
Ten kod nie jest świetny. Po pierwsze, nie potrzebujesz zagnieżdżonej pętli, która wielokrotnie (<liczba kolumn>) ustawia tryb szerokości wszystkich kolumn na tę samą rzecz; można uzyskać dostęp do właściwości AutoSizeMode i FillWeight każdej kolumny bezpośrednio z GridCol. Po drugie, ustawia AutoSizeMode dla każdej kolumny na dwie różne wartości; drugie przypisanie nadpisze pierwsze.
JonP
0

Aby oprzeć się na odpowiedzi AlfredBra, jeśli ukryłeś niektóre kolumny, możesz użyć poniższego, aby automatycznie zmienić rozmiar wszystkich kolumn, a następnie po prostu ostatnia widoczna kolumna wypełni puste miejsce:

myDgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
myDgv.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None).AutoSizeMode = 
    DataGridViewAutoSizeColumnMode.Fill;
RooiWillie
źródło
0

Oto, co zrobiłem, aby kolumna „first_name” wypełniła miejsce, gdy wszystkie kolumny nie mogą tego zrobić.

Kiedy siatka staje się mała, kolumna „first_name” staje się prawie niewidoczna (bardzo cienka), więc mogę ustawić DataGridViewAutoSizeColumnMode na AllCells jako inne widoczne kolumny. W przypadku problemów z wydajnością ważne jest, aby ustawić je na None przed powiązaniem ich danych i ustawić z powrotem na AllCell w module obsługi zdarzeń DataBindingComplete w siatce. Mam nadzieję, że to pomoże!

private void dataGridView1_Resize(object sender, EventArgs e)
    {
        int ColumnsWidth = 0;
        foreach(DataGridViewColumn col in dataGridView1.Columns)
        {
            if (col.Visible) ColumnsWidth += col.Width;
        }

        if (ColumnsWidth <dataGridView1.Width)
        {
            dataGridView1.Columns["first_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }
        else if (dataGridView1.Columns["first_name"].Width < 10) dataGridView1.Columns["first_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
Ignacio
źródło
-1
public void setHeight(DataGridView src)
{
    src.Height= src.ColumnHeadersVisible ? src.ColumnHeadersHeight : 0 +   src.Rows.OfType<DataGridViewRow>().Where(row => row.Visible).Sum(row => row.Height);
}
Durga Prasad Guntoju
źródło
po prostu wywołaj tę funkcję, zajmie się określeniem wysokości datagridview na podstawie liczby wierszy w nim
Durga Prasad Guntoju
1
Przede wszystkim nie jest to odpowiedź na pytanie PO. Uwzględnij również (na przyszłość) taki komentarz do samej odpowiedzi (możesz go edytować).
Joel
-2

Spróbuj tego :

  DGV.AutoResizeColumns();
  DGV.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.AllCells;
Sudhir
źródło