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?
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.
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) .
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
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.
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.
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
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.
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.
Das hat Wunder für mich getan:
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
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;
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;
}
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;
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.
dataGridView1.AutoResizeColumns ();
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;
}
Eine einfache zwei Zeilen Code funktioniert für mich.
dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
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;
}
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.
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. 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.
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
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.
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.
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;
}