web-dev-qa-db-de.com

Wie können Sie die Größe von Spalten in einem DataGridView-Steuerelement automatisch ändern UND dem Benutzer die Änderung der Spalten in demselben Raster ermöglichen?

Ich fülle ein DataGridView-Steuerelement in einem Windows Form (C # 2.0 nicht WPF).

Mein Ziel ist es, ein Raster anzuzeigen, das die gesamte verfügbare Breite sauber mit Zellen ausfüllt, d. H. Keine unbenutzten (dunkelgrauen) Bereiche rechts und jede Spalte entsprechend den darin enthaltenen Daten. aber Erlaubt dem Benutzer außerdem, die Größe der Spalten nach Belieben zu ändern.

Ich versuche dies zu erreichen, indem ich den AutoSizeMode für jede Spalte auf DataGridViewAutoSizeColumnMode.AllCells setze, außer für eine der Spalten, die ich auf DataGridViewAutoSizeColumnMode.Fill gesetzt habe, um sicherzustellen, dass der gesamte Bereich des Gitters ist ordentlich gefüllt mit Daten. (Es macht mir nichts aus, dass der Benutzer, wenn er versucht, die Größe dieser Spalte zu ändern, auf eine Größe zurückfällt, die sicherstellt, dass der horizontale Abstand immer verwendet wird.)

Wie bereits erwähnt, möchte ich dem Benutzer nach dem Laden die Größe der Spalten an ihre eigenen Anforderungen anpassen. Wenn Sie diese AutoSizeMode-Werte für jede Spalte festlegen, scheint der Benutzer diese Spalten dann nicht zu ändern.

Ich habe versucht, den AutoSizeMode nicht für alle Spalten festzulegen, wodurch die Größe geändert werden kann. Die Ausgangsgröße wird jedoch nicht entsprechend den in den Zellen enthaltenen Daten festgelegt. Das gleiche Ergebnis tritt auf, wenn der AutoSizeMode des Rasters nach dem Laden der Daten wieder auf "Nicht festgelegt" gesetzt wird.

Gibt es eine Einstellung, die mir fehlt, die das automatische Einstellen der Standardspaltenbreite UND die Änderung der Benutzergröße ermöglicht, oder gibt es eine andere Technik, die ich beim Füllen des DataGridView-Steuerelements verwenden muss?

98
Stuart Helwig

Dieser Trick funktioniert für mich:

grd.DataSource = DT;

//set autosize mode
grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

//datagrid has calculated it's widths so we can store them
for (int i = 0; i <= grd.Columns.Count - 1; i++) {
    //store autosized widths
    int colw = grd.Columns[i].Width;
    //remove autosizing
    grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    //set width to calculated by autosize
    grd.Columns[i].Width = colw;
}

Was hier passiert, ist, dass Sie für den AutoSize-Modus den gewünschten Modus einstellen und dann Spalte für Spalte die Breite speichern, die er aus der AutoSize-Berechnung erhalten hat.

115

Vielleicht könntest du anrufen

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

Nach dem Einstellen der Datenquelle. Damit wird die Breite festgelegt und die Größenänderung ermöglicht.

Weitere Informationen zu MSDN DataGridView.AutoResizeColumns-Methode (DataGridViewAutoSizeColumnsMode) .

38
Umair

Eine C # -Version von Miroslav Zadravecs Code

for (int i = 0; i < dataGridView1.Columns.Count-1; i++)
{
    dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
    int colw = dataGridView1.Columns[i].Width;
    dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dataGridView1.Columns[i].Width = colw;
}

Gepostet als Community-Wiki, um nicht den Ruf anderer zu beeinträchtigen

28
Tom Kidd

In meiner Bewerbung habe ich eingestellt

grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;

Auch habe ich das eingestellt 

grid.AllowUserToOrderColumns = true;
grid.AllowUserToResizeColumns = true;

Nun können die Spaltenbreiten geändert und die Spalten vom Benutzer neu angeordnet werden. Das funktioniert ziemlich gut für mich.

Vielleicht klappt das für Sie.

11
Jehof

Nun, ich habe das so gemacht:

dgvReport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgvReport.AutoResizeColumns();
dgvReport.AllowUserToResizeColumns = true;
dgvReport.AllowUserToOrderColumns = true;

in dieser besonderen Reihenfolge. Spalten werden in der Größe geändert (erweitert) UND der Benutzer kann die Größe der Spalten anschließend ändern.

8
mpss

Fügen Sie nach dem Hinzufügen der Daten zum Raster den folgenden Code hinzu, der die Spalte entsprechend der Länge der Daten in jeder Zelle anpasst

dataGrid1.AutoResizeColumns();            
dataGrid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

Hier ist das Ergebnis

enter image description here

7
Sarath Avanavu

Wenn ich die Frage richtig verstanden habe, sollte es einen einfacheren Weg geben, um das zu erreichen, was Sie brauchen. Rufen Sie an dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

Das sollte den Trick tun. Es gibt jedoch eine Gefahr, da Sie diese Methode nicht direkt nach dem Auffüllen Ihres DataGridView-Steuerelements aufrufen können. Stattdessen müssen Sie einen EventHandler für das VisibleChanged-Ereignis hinzufügen und die Methode dort aufrufen.

6
Gorgsenegger

Zusammenfassung der Frage:
Spaltenbreite an den Inhalt anpassen (mit unterschiedlicher Methode in der Spalte),
Erlauben Sie dem Benutzer dann, die Spaltenbreite einzustellen ...

Entwicklung von Miroslav Zadravecs Antwort , was für mich funktionierte, war sofort die Verwendung des automatisch berechneten column.Width, um einzustellen ... column.Width!

foreach (DataGridViewColumn column in dataGridView.Columns)
{
    if (/*It's not your special column*/)
    {
        column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        column.Width = column.Width; //This is important, otherwise the following line will nullify your previous command
        column.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
    }
}

//Now do the same using Fill instead of AllCells for your special column

Dies wird getestet, wenn die DataGridView bereits mit einem Trick wie this erstellt wurde.

4
Antonio

Das hat Wunder für mich getan: 

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
3
Vaishali

Hier ist ein vereinfachter Code für die Antwort von Miroslav Zadravec in c #:

CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
for (int i = 0; i < dataGridView1.Columns.Count; i++) dataGridView1.Columns[i].Width = dataGridView1.Columns[i].Width;
CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
2
Cassio Accioly

Etwas klarer C # -Code aus dem Code von Miroslav Zadravec, sofern alle Spalten automatisch formatiert werden

for (int i = 0; i < dgvProblems.Columns.Count; i++)
{
    dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    int colw = dgvProblems.Columns[i].Width;
    dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dgvProblems.Columns[i].Width = colw;
}
2
Rob

Dadurch werden alle Spalten automatisch anhand ihres Inhalts angepasst, der verbleibende leere Speicherplatz wird durch Dehnen einer angegebenen Spalte aufgefüllt und das 'Jumping' -Verhalten wird verhindert, indem die letzte Spalte für zukünftige Größenänderungen gefüllt wird.

// autosize all columns according to their content
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
// make column 1 (or whatever) fill the empty space
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
// remove column 1 autosizing to prevent 'jumping' behaviour
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
// let the last column fill the empty space when the grid or any column is resized (more natural/expected behaviour) 
dgv.Columns.GetLastColumn(DataGridViewElementStates.None, DataGridViewElementStates.None).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
2
wnutt

Eine andere Version von Miroslav Zadravecs Code, jedoch etwas automatisierter und universeller:

    public Form1()
    {
        InitializeComponent();
        dataGridView1.DataSource = source;
        for (int i = 0; i < dataGridView1.Columns.Count - 1; i++) {
            dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }
        dataGridView1.Columns[dataGridView1.Columns.Count].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

    }

    void Form1Shown(object sender, EventArgs e)
    {
        for ( int i = 0; i < dataGridView1.Columns.Count; i++ )
        {
            int colw = dataGridView1.Columns[i].Width;
            dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            dataGridView1.Columns[i].Width = colw;
        }
    }

Ich füge den zweiten Teil in ein separates Ereignis ein, weil ich datagridvew in der Initialisierung der Form ausfülle, und wenn beide Teile vorhanden sind, ändert sich nichts, da wahrscheinlich autosize Breiten berechnet, nachdem datagridview angezeigt wird. Daher sind die Breiten in der Form1() Methode immer noch voreingestellt . Nachdem Sie diese Methode beendet haben, führt autosize ihren Trick aus und unmittelbar danach (wenn das Formular angezeigt wird) können Sie die Breiten durch den zweiten Teil des Codes festlegen (hier in Form1Shown-Ereignis). Das funktioniert für mich wie ein Zauber.

2
LQd

dataGridView1.AutoResizeColumns ();

1

Die Spaltenbreiten wurden auf den Inhalt angepasst. Ich habe die folgende Anweisung verwendet: Das Problem wurde behoben.

Erster Schritt : 

RadGridViewName.AutoSize = true;

Zweiter Schritt :

// This mode  fit in the header text and column data for all visible rows. 
this.grdSpec.MasterTemplate.BestFitColumns();

Dritter Schritt : 

for (int i = 0; i < grdSpec.Columns.Count; i++) 
{
    // The column width adjusts to fit the contents all cells in the control.
    grdSpec.Columns[i].AutoSizeMode = BestFitColumnMode.AllCells; 
}
1
Priyanka

Eine einfache zwei Zeilen Code funktioniert für mich.

dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
1
Rashmin Javiya

Eine kleine Verbesserung gegenüber der Schnapple-Version

int nLastColumn = dgv.Columns.Count - 1;
for (int i = 0; i < dgv.Columns.Count; i++)
{
    if (nLastColumn == i)
    {
        dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }
    else
    {
        dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
}

for (int i = 0; i < dgv.Columns.Count; i++)
{
    int colw = dgv.Columns[i].Width;
    dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dgv.Columns[i].Width = colw;
}
1
Initrof

Haben Sie versucht, die FillWeight-Eigenschaft Ihres DataGridViewColumns-Objekts einzurichten?

Zum Beispiel:

this.grid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.grid1.Columns[0].FillWeight = 1.5;

Ich denke, es sollte in Ihrem Fall funktionieren.

1
Rubanovsky Alex
  • Vielen Dank für die Lösung oben (Um den DataGridView.Columns zu durchlaufen, ändern Sie AutoSizeMode in einen gültigen Wert, sammeln Sie den Breitenwert und setzen Sie ihn nach der Änderung von AutoSizeMode auf DataGridViewAutoSizeColumnMode.None zurück. 
  • Ich hatte Schwierigkeiten damit und bemerkte, dass es nicht funktioniert, wenn es vom Klassenkonstruktor oder einer anderen Zeile vor Form.Show() oder Form.ShowDialog() aufgerufen wird. Also habe ich dieses Code-Snippet in das Form.Shown-Ereignis eingefügt und das funktioniert für mich. 
  • Mein transformierter Code, der ohne Rücksicht auf den zuvor festgelegten DataGridView.AutoSizeColumnsMode ist, benutze DataGridViewColumn.GetPreferredWidth(), anstatt DataGridViewColumn.AutoSizeMode zu ändern und den Wert für die Breite sofort einzustellen. Dann DataGridView.AutoSizeColumnsMode einmal ändern: 

    private void form_Shown(object sender, EventArgs e)
    {
            foreach (DataGridViewColumn c in dataGridView.Columns)
                c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.DisplayedCells, true);
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
    }
    
  • Stellen Sie sicher, dass Sie eingestellt sind 

            dataGridView.AllowUserToResizeColumns = true;
    
  • Ich weiß nicht, wie es funktioniert, nachdem das Formular gezeigt wurde.

0
user1779049

Ich musste dies in VB tun und es vorziehen, es auf eine Methode aufzuteilen, die ich in ein Modul eingefügt habe. Sie können die Fill-Spalte bei Bedarf als einen weiteren ByRef-Parameter hinzufügen.

''' <summary>
''' Makes all columns in a DataGridView autosize based on displayed cells,
''' while leaving the column widths user-adjustable.
''' </summary>
''' <param name="dgv">A DataGridView to adjust</param>
Friend Sub MakeAdjustableAutoSizedGridCols(ByRef dgv As DataGridView)
    Dim width As Integer

    For Each col As DataGridViewColumn In dgv.Columns
        col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
        width = col.Width
        col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None
        col.Width = width
    Next
    dgv.AllowUserToResizeColumns = True
End Sub
0
Greg Barth
foreach (DataGridViewColumn c in dataGridView.Columns)
    c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);

Dies sollte funktionieren, ob die Variable dataGridView angezeigt wurde oder nicht (d. H. Auch wenn sie vom Klassenkonstruktor aufgerufen wird).

Dieselbe Methode, jedoch mit DataGridViewAutoSizeColumnMode.DisplayedCells, schlägt in dem oben genannten Fall aus dem offensichtlichen Grund fehl - es wurde noch keine Zelle angezeigt! Aus irgendeinem nicht offensichtlichen Grund schlägt auch AutoResizeColumns in diesem Fall fehl.

0

Sie könnten so etwas tun:

   grd.DataSource = getDataSource();

    if (grd.ColumnCount > 1)
    {
        for (int i = 0; i < grd.ColumnCount-1; i++)
            grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

        grd.Columns[grd.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }

    if (grd.ColumnCount==1)
        grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

Alle Spalten passen sich dem Inhalt an, außer der letzten füllt das Raster.

0
usr4217

Wenn Sie Ihre Datenquelle beispielsweise an eine Datentabelle binden, müssen Sie die Eigenschaften festlegen, nachdem die Bindung abgeschlossen ist:

        private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dgv.AutoResizeColumns();
            dgv.AllowUserToResizeColumns = true;
        }
0
ehh