Laden...

Datagrid datasource zu langsam bei vielen Spalten (>100)

Erstellt von Mary81 vor 10 Jahren Letzter Beitrag vor 10 Jahren 4.625 Views
M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren
Datagrid datasource zu langsam bei vielen Spalten (>100)

Hallo zusammen,

ich habe ein Problem mit meinem DataGrid.
Und zwar weiße ich dem DG eine DataTable zu. Diese DataTable baue ich vorher auf, d.h. X Columns und X Rows.

Code: DataGridView.DataSource = _myTable;

Mein Problem:

wenn ich mehr als 100 Spalten in der Tabelle habe und ca. 12 Zeilen. Dann dauer die zuweisund (DataGridView.DataSource = _myTable) fast 15 sek.

Kann man das schneller hinkriegen??

Danke & Gruß

F
10.010 Beiträge seit 2004
vor 10 Jahren

Klar, indem du AutoSizeColumnsMode und/oder AutoSizeRowsMode ausschaltest.
Beides führt zu haufenweise Neuberechnungen über den gesamten Datenbestand.

Aber bei der Menge an Daten sind 15 Sekunden deutlich zu viel, selbst damit.

Sind da noch Format Eventhandler oder sonstige Events im spiel?

A
764 Beiträge seit 2007
vor 10 Jahren

Hallo Mary81,

es hilft auch, das Neuzeichnen des DGV, während des Ladens, zu verhindern. Ich weiss jetzt leider nicht aus dem Kopf, wie das geht.

Gruß, Alf

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

das bringt leider nicht viel.

datagridview.SuspendLayout();

datagridview.Columns.Clear();
datagridview.DataSource = _myTable;

datagridview.ResumeLayout();

Damit bin ich immer noch über 10 sec.

F
10.010 Beiträge seit 2004
vor 10 Jahren

Da ein normales DGV mit zig spalten und tausenden von Zeilen im Normalfall in Sekundenbruchteilen aufgebaut ist, muss etwas bei deinen Einstellungen sein, das das so langsam ist.

Zeig mal den Teil der Designer.CS wo das DGV angelegt wird.

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

//
// datagridviewMasstabelle
//
this.datagridviewMasstabelle.AllowUserToAddRows = false;
this.datagridviewMasstabelle.AllowUserToDeleteRows = false;
this.datagridviewMasstabelle.AllowUserToResizeRows = false;
resources.ApplyResources(this.datagridviewMasstabelle, "datagridviewMasstabelle");
this.datagridviewMasstabelle.BackgroundColor = System.Drawing.Color.White;
this.datagridviewMasstabelle.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
this.datagridviewMasstabelle.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
this.datagridviewMasstabelle.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.datagridviewMasstabelleMassID,
this.datagridviewMasstabelleMassbezeichnung,
this.datagridviewMasstabelleEinheit});
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.datagridviewMasstabelle.DefaultCellStyle = dataGridViewCellStyle2;
this.datagridviewMasstabelle.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter;
this.datagridviewMasstabelle.Name = "datagridviewMasstabelle";
dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle3.BackColor = System.Drawing.Color.White;
dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle3.ForeColor = System.Drawing.Color.Black;
dataGridViewCellStyle3.SelectionBackColor = System.Drawing.Color.White;
dataGridViewCellStyle3.SelectionForeColor = System.Drawing.Color.Black;
dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.datagridviewMasstabelle.RowHeadersDefaultCellStyle = dataGridViewCellStyle3;
this.datagridviewMasstabelle.RowHeadersVisible = false;
this.datagridviewMasstabelle.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this.datagridviewMasstabelle.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
this.datagridviewMasstabelle.ShowCellErrors = false;
this.datagridviewMasstabelle.ShowCellToolTips = false;
this.datagridviewMasstabelle.ShowEditingIcon = false;
this.datagridviewMasstabelle.ShowRowErrors = false;
this.datagridviewMasstabelle.DataSourceChanged += new System.EventHandler(this.datagridviewMasstabelle_DataSourceChanged);
this.datagridviewMasstabelle.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.datagridviewMasstabelle_DataError);

F
10.010 Beiträge seit 2004
vor 10 Jahren

Wenn Du dir schon die Mühe machst die Spalten anzulegen, solltest Du AutoGenerateColumsn ausschlten.

Und was macht datagridviewMasstabelle_DataSourceChanged?

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

die datagridviewMasstabelle_DataSourceChanged sorg dafür das meine Tabelle in den richtigen Format gebracht wird.
Heißt: die ersten beiden Spalten müssen auf ReadOnly=true gesetzt werden und alle Spalten bekommen die Eigenschaften:

for (int i = 3; i < datagridviewMasstabelle.ColumnCount; i++)
{
   datagridviewMasstabelle.Columns[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
   datagridviewMasstabelle.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}

Ich hab festgestellt wenn ich die For-Schleife auskommentiere, dann wird das Grid unter 1 sek. geladen.

W
955 Beiträge seit 2010
vor 10 Jahren

Hi,

ich denke das s teuer ist für jede Spalte die Attribute zuzuweisen. Es gibt doch Zell-Schablonen für das gesamte DGV. Warum setzt Du nicht einfach diese und überschreibst für die ersten beiden Spalten dann auf Spaltenebene?

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

Hi,

die AutoSizeMode kann ich setzten, aber für die
datagridviewMasstabelle.Columns_.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

kann ich nichts finden.

Hast du eine Idee was ich noch machen kann??

F
10.010 Beiträge seit 2004
vor 10 Jahren
AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

Bedeutet das er jedes Feld durchgeht und da du hier bereits bei Änderungen zeichnest müsstest du diese Schleife eben mit Suspend/ResumeLayout umgeben.

Besser wäre aber wie oben schon gesagt, die Spalten anlegen und dann AutoGenerateColumns auszuschalten.

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

Ich hab's gefunden!!!!

Es läuft!!!!!! Es wird in max. 2 sek. alles geladen 😃

Besten Dank an alle !!!!!!!!!

T
156 Beiträge seit 2012
vor 10 Jahren

Hallo Mary81,

gratuliere Dir zur Lösung der Sache.
Kannst Du uns einige Hinweise geben was da zur Zeitverzögerung geführt hat und wie Du das beheben konntest?

Viele Grüße,
telfa

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

Hallo telfa,

danke!

Das Problem lag wirklich an der for-Schleife in

private void datagridviewMasstabelle_DataSourceChanged(object sender, EventArgs e)
{
   ... 
   for (int i = 3; i < datagridviewMasstabelle.ColumnCount; i++)
   {
      datagridviewMasstabelle.Columns[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
      datagridviewMasstabelle.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
   }
   ...
}

ich habe die Einstellungen für Alignment = MiddleCenter und AutoSizeMode = AllCells in den Eigenschaften für das gesamte DGV eingestellt und vor jedem neu laden wird das AutoGenerateColumsn auf false gesetzt und nach dem zuweisen wieder auf true.

Somit läft das ganze unter 2 sek. bei wirklich großen listen kanns schon mal 2-3 sek. dauern. Aber das ist vollkommen in Ordnung.

Besten Dank nochmal an euch allen!!!!

Schöne Grüße

F
10.010 Beiträge seit 2004
vor 10 Jahren

Äh wie?
AutoGenerateColumns wird nur bedacht wenn du die DataSource zuweist, du musst das also nicht hin und her ändern.
Und wenn du sowieso alle Spalten vorher anlegst, musst du diese Schleife überhaupt nicht machen.

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

Hi,

in meiner UI habe ich zwei DGV. Die Erste hat bestimmte Werte. Wenn ich da was auswähle, dann bekommt meine datagridviewMasstabelle eine neue DataSource zugewiesen. Wenn ich aber die AutoGenerateColumns nach der Zuweisung nicht wieder auf true setzte, dann wird mir nichts angezeigt.

Die Schleife muss ich auf jeden Fall nicht mehr ausführen, was ich auch nicht mehr mache. Dadurch wird das ganze auch ziemlich schnell!

T
156 Beiträge seit 2012
vor 10 Jahren

Hallo Mary81,

vielleicht wäre es einfacher mit zwei DGV zu arbeiten, die Du per Event ein- bzw ausblendest. Das ist jetzt ein spontaner Gedanke ohne Deine Anwendung näher zu kennen.

Viele Grüße,
telfa

M
Mary81 Themenstarter:in
87 Beiträge seit 2008
vor 10 Jahren

Nein, nein. Das ist nicht die Funktion!

DGV hat z. B. Wert A, B, C
DGV zeigt die Eigenschaft zu A (wenn diese oben ausgewählt ist): aa, ab, ac, ad etc.
zu B: b123, b133, b155 etc
zu C: zu34, zu56, zu99 etc

ich muss die beiten DGV immer sehen. Deswegen bekommt die zweite Grid immer eine neue DataSource, wenn ich im ersten DGV was auswähle.

F
10.010 Beiträge seit 2004
vor 10 Jahren

Da hast du etwas komplett falsch verstanden.

AutoGenerateColumns bedeutet das das DGV versucht nach dem zuweisen einer neuen DataSource die Columns neu anzulegen, passend zur neuen Auflistung.

Wenn du aber AutoGenerateColumns immer aus hast, und alle Columns vorher anlegst, brauchst du da nichts machen, denn dafür ist das gedacht.