Empfohlene Vorgehensweisen für das Skalieren des DataGridView-Steuerelements in Windows Forms
Aktualisiert: November 2007
Das DataGridView-Steuerelement ist für maximale Skalierbarkeit ausgelegt. Wenn Sie umfangreiche Datenmengen anzeigen müssen, sollten Sie die in diesem Thema beschriebenen Richtlinien befolgen, um zu verhindern, dass der Arbeitsspeicher überlastet oder die Reaktionsfähigkeit der Benutzeroberfläche beeinträchtigt wird. In diesem Thema werden folgende Aspekte behandelt:
Effiziente Verwendung von Zellenstilen
Effiziente Verwendung von Kontextmenüs
Effiziente Verwendung der automatischen Größenanpassung
Effiziente Verwendung der Auflistungen für ausgewählte Zellen, Zeilen und Spalten
Verwenden freigegebener Zeilen
Verhindern, dass die Zeilenfreigabe aufgehoben wird
Bei besonderen Leistungsanforderungen können Sie den virtuellen Modus implementieren und eigene Datenverwaltungsoperationen bereitstellen. Weitere Informationen finden Sie unter Datenanzeigemodi im DataGridView-Steuerelement in Windows Forms.
Effiziente Verwendung von Zellenstilen
Jede Zelle, Zeile und Spalte kann eigene Formatinformationen haben. Formatinformationen werden in DataGridViewCellStyle-Objekten gespeichert. Das Erstellen von Zellenstilobjekten für viele einzelne DataGridView-Elemente kann sich als ineffizient erweisen, besonders bei der Bearbeitung umfangreicher Datenmengen. Befolgen Sie die nachstehenden Richtlinien, um Leistungseinbußen zu vermeiden:
Legen Sie keine Zellenstileigenschaften für ein einzelnes DataGridViewCell-Objekt oder DataGridViewRow-Objekt fest. Dies schließt das von der RowTemplate-Eigenschaft angegebene Zeilenobjekt ein. Jeder von der Zeilenvorlage geklonten neuen Zeile wird eine eigene Kopie des Zellenstilobjekts der Vorlage zugewiesen. Um maximale Skalierbarkeit zu erzielen, sollten Sie die Zellenstileigenschaften auf DataGridView-Ebene festlegen. Legen Sie beispielsweise die DataGridView.DefaultCellStyle-Eigenschaft anstelle der DataGridViewCell.Style-Eigenschaft fest.
Falls einige Zellen eine vom Standardformat abweichende Formatierung erfordern, verwenden Sie dieselbe DataGridViewCellStyle-Instanz übergreifend für Zellen-, Zeilen- oder Spaltengruppen. Vermeiden Sie es, Eigenschaften des Typs DataGridViewCellStyle für einzelne Zellen, Zeilen und Spalten direkt festzulegen. Ein Beispiel für die Freigabe von Zellenstilen finden Sie unter Gewusst wie: Festlegen von Standardzellenformaten für das DataGridView-Steuerelement in Windows Forms. Sie können außerdem eine Leistungsminderung beim Festlegen individueller Zellenstile vermeiden, indem Sie den CellFormatting-Ereignishandler behandeln. Ein Beispiel finden Sie unter Gewusst wie: Anpassen der Datenformatierung im DataGridView-Steuerelement in Windows Forms.
Verwenden Sie beim Festlegen eines Zellenstils die DataGridViewCell.InheritedStyle-Eigenschaft anstelle der DataGridViewCell.Style-Eigenschaft. Beim Zugriff auf die Style-Eigenschaft wird eine neue Instanz der DataGridViewCellStyle-Klasse erstellt, falls die Eigenschaft noch nicht verwendet wurde. Außerdem enthält dieses Objekt u. U. nicht die vollständigen Formatinformation für die Zelle, wenn einige Stile von der Zeile bzw. Spalte oder dem Steuerelement geerbt wurden. Weitere Informationen über die Vererbung von Zellenstilen finden Sie unter Zellstile im DataGridView-Steuerelement in Windows Forms.
Effiziente Verwendung von Kontextmenüs
Jede Zelle, Zeile und Spalte kann über ein eigenes Kontextmenü verfügen. Kontextmenüs werden im DataGridView-Steuerelement durch ContextMenuStrip-Steuerelemente dargestellt. Genauso wie bei Zellenstilobjekten hat das Erstellen von Kontextmenüs für viele einzelne DataGridView-Elemente negative Auswirkungen auf die Systemleistung. Um diese Leistungsminderung zu vermeiden, beachten Sie die folgenden Richtlinien:
Erstellen Sie keine Kontextmenüs für einzelne Zellen und Zeilen. Dies gilt auch für die Zeilenvorlage, die zusammen mit ihrem Kontextmenü geklont wird, sobald dem Steuerelement neue Zeilen hinzugefügt werden. Um optimale Skalierbarkeit zu gewährleisten, verwenden Sie ausschließlich die ContextMenuStrip-Eigenschaft des Steuerelements, um ein einziges Kontextmenü für das gesamte Steuerelement zu erstellen.
Wenn Sie mehrere Kontextmenüs für mehrere Zeilen oder Zellen benötigen, behandeln Sie das CellContextMenuStripNeeded-Ereignis oder das RowContextMenuStripNeeded-Ereignis. Diese Ereignisse ermöglichen es Ihnen, die Kontextmenüobjekte selbst zu verwalten und so die Leistung zu optimieren.
Effiziente Verwendung der automatischen Größenanpassung
Die Größe von Zeilen, Spalten und Headern kann in Anpassung an veränderte Zellinhalte automatisch geändert werden, damit der gesamte Inhalt der Zellen sichtbar ist und keine Informationen abgeschnitten werden. Durch das Ändern von Größenanpassungsmodi kann auch die Größe von Zeilen, Spalten und Headern geändert werden. Um die richtige Größe zu bestimmen, muss das DataGridView-Steuerelement den Wert jeder Zelle überprüfen, die es aufnehmen muss. Bei der Arbeit mit umfangreichen Datasets kann sich diese Analyse bei einer automatischen Größenanpassung negativ auf die Steuerelementleistung auswirken. Um Leistungsminderungen zu vermeiden, beachten Sie die folgenden Richtlinien:
Verzichten Sie bei einem DataGridView-Steuerelement mit umfangreichen Rowsets auf die automatische Größenanpassung. Wenn Sie die automatische Größenanpassung trotzdem verwenden, führen Sie die Anpassung nur auf der Grundlage der angezeigten Zeilen aus. Auch im virtuellen Modus sollten nur die angezeigten Zeilen verwendet werden.
Verwenden Sie für Zeilen und Spalten das DisplayedCells-Feld oder das DisplayedCellsExceptHeaders-Feld der Enumerationen DataGridViewAutoSizeRowsMode, DataGridViewAutoSizeColumnsMode und DataGridViewAutoSizeColumnMode.
Verwenden Sie für Zeilenheader das AutoSizeToDisplayedHeaders-Feld oder das AutoSizeToFirstHeader-Feld der DataGridViewRowHeadersWidthSizeMode-Enumeration.
Deaktivieren Sie die automatische Größenanpassung, und verwenden Sie die programmgesteuerte Größenanpassung, um optimale Skalierbarkeit zu erzielen.
Weitere Informationen finden Sie unter Größenänderungsoptionen im DataGridView-Steuerelement in Windows Forms.
Effiziente Verwendung der Auflistungen für ausgewählte Zellen, Zeilen und Spalten
Die SelectedCells-Auflistung bietet bei umfangreichen Auswahlen keine effiziente Leistung. Auch die SelectedRows-Auflistung und die SelectedColumns-Auflistung können sich ineffizient erweisen – wenn auch in einem geringeren Grad. Dies liegt daran, dass ein typisches DataGridView-Steuerelement wesentlich weniger Zeilen als Zellen und wesentlich weniger Spalten als Zeilen enthält. Um Leistungseinbußen bei Verwendung dieser Auflistungen zu vermeiden, beachten Sie die folgenden Richtlinien:
Um festzustellen, ob alle Zellen in DataGridView ausgewählt wurden, bevor Sie auf den Inhalt der SelectedCells-Auflistung zugreifen, überprüfen Sie den Rückgabewert der AreAllCellsSelected-Methode. Diese Methode kann jedoch bewirken, dass die Freigabe von Zeilen aufgehoben wird. Weitere Informationen finden Sie im nächsten Abschnitt.
Vermeiden Sie es, die Count-Eigenschaft von System.Windows.Forms.DataGridViewSelectedCellCollection zu verwenden, um die Anzahl ausgewählter Zellen zu ermitteln. Verwenden Sie stattdessen die DataGridView.GetCellCount-Methode, und übergeben Sie den DataGridViewElementStates.Selected-Wert. Entsprechend sollten Sie die DataGridViewRowCollection.GetRowCount-Methode und die DataGridViewColumnCollection.GetColumnCount-Methode verwenden, um die Anzahl ausgewählter Elemente zu ermitteln, anstatt auf die Auflistungen für ausgewählte Zeilen und Spalten zuzugreifen.
Vermeiden Sie zellenbasierte Auswahlmodi. Legen Sie stattdessen die DataGridView.SelectionMode-Eigenschaft auf DataGridViewSelectionMode.FullRowSelect oder DataGridViewSelectionMode.FullColumnSelect fest.
Verwenden freigegebener Zeilen
Eine effiziente Speichernutzung wird im DataGridView-Steuerelement durch freigegebene Zeilen erreicht. Dabei werden von den Zeilen möglichst viele Informationen über Zeilendarstellung und -verhalten gemeinsam genutzt, indem Instanzen der DataGridViewRow-Klasse freigegeben werden.
Die gemeinsame Nutzung von Zeileninstanzen entlastet zwar den Arbeitsspeicher, kann aber dazu führen, dass die Freigabe von Zeilen aufgehoben wird. Beispielsweise wird jedes Mal, wenn ein Benutzer direkt mit einer Zelle interagiert, die Freigabe der betreffenden Zeile aufgehoben. Da dieses Verhalten nicht unterbunden werden kann, sind die Richtlinien in diesem Thema nur bei der Arbeit mit sehr großen Datenmengen hilfreich und auch nur dann, wenn Benutzer bei jeder Ausführung des Programms mit einem relativ geringen Teil der Daten interagieren.
Eine Zeile kann in einem ungebundenen DataGridView-Steuerelement nicht freigegeben werden, wenn eine ihrer Zellen Werte enthält. Wenn das DataGridView-Steuerelement an eine externe Datenquelle gebunden ist, oder wenn Sie den virtuellen Modus implementieren und eine eigene Datenquelle bereitstellen, werden die Zellwerte außerhalb des Steuerelements und nicht in Zellobjekten gespeichert, wodurch die Zeilen freigegeben werden können.
Ein Zeilenobjekt kann nur freigegeben werden, wenn der Zustand all seiner Zellen über den Zustand der Zeile und den jeweiligen Zustand der Spalten ermittelt werden kann, in denen die Zellen enthalten sind. Wenn Sie den Zustand einer Zelle ändern, sodass er nicht mehr vom Zustand der zugehörigen Zeile und Spalte abgeleitet werden kann, kann die Zeile nicht freigegeben werden.
Beispielsweise können Zeilen in folgenden Situationen nicht freigegeben werden:
Die Zeile enthält eine einzelne ausgewählte Zelle, die sich nicht in einer ausgewählten Spalte befindet.
Die Zeile enthält eine Zelle, deren ToolTipText-Eigenschaft oder ContextMenuStrip-Eigenschaft festgelegt ist.
Die Zeile enthält DataGridViewComboBoxCell mit festgelegter Items-Eigenschaft.
Im gebundenen oder virtuellen Modus können Sie QuickInfos und Kontextmenüs für einzelne Zellen bereitstellen, indem Sie das CellToolTipTextNeeded-Ereignis und das CellContextMenuStripNeeded-Ereignis behandeln.
Das DataGridView-Steuerelement versucht automatisch, freigegebene Zeilen zu verwenden, sobald DataGridViewRowCollection Zeilen hinzugefügt werden. Beachten Sie die folgenden Richtlinien, um sicherzustellen, dass die Zeilenfreigabe erhalten bleibt:
Vermeiden Sie es, die Add(Object[])-Überladung der Add-Methode und die Insert(Object[])-Überladung der Insert-Methode aus der DataGridView.Rows-Auflistung aufzurufen. Durch diese Überladungen wird die Freigabe von Zeilen automatisch aufgehoben.
Stellen Sie sicher, dass die Freigabe der in der DataGridView.RowTemplate-Eigenschaft angegebenen Zeile in den folgenden Fällen erhalten bleibt:
Beim Aufrufen der Add()-Überladung oder der Add(Int32)-Überladung der Add-Methode bzw. der Insert(Int32,Int32)-Überladung der Insert-Methode aus der DataGridView.Rows-Auflistung
Beim Erhöhen des Werts der DataGridView.RowCount-Eigenschaft
Beim Festlegen der DataGridView.DataSource-Eigenschaft
Achten Sie darauf, dass die Freigabe der durch den indexSource-Parameter angegebenen Zeile erhalten bleibt, wenn die Methoden AddCopy, AddCopies, InsertCopy und InsertCopies der DataGridView.Rows-Auflistung aufgerufen werden.
Achten Sie darauf, dass die Freigabe der angegebenen Zeile(n) erhalten bleibt, wenn die Add(DataGridViewRow)-Überladung der Add-Methode, die AddRange-Methode, die Insert(Int32,DataGridViewRow)-Überladung der Insert-Methode und die InsertRange-Methode aus der DataGridView.Rows-Auflistung aufgerufen werden.
Um festzustellen, ob eine Zeile freigegeben ist, rufen Sie das Zeilenobjekt mit der DataGridViewRowCollection.SharedRow-Methode ab und überprüfen dann die Index-Eigenschaft des Objekts. Freigegebene Zeilen verfügen immer über einen Index-Eigenschaftenwert von -1.
Verhindern, dass die Zeilenfreigabe aufgehoben wird
Die Freigabe von Zeilen kann durch Code oder aufgrund einer Benutzeraktion aufgehoben werden. Um Auswirkungen auf die Systemleistung zu vermeiden, sollten Sie darauf achten, dass die Freigabe von Zeilen nicht aufgehoben wird. Während der Anwendungsentwicklung können Sie das RowUnshared-Ereignis behandeln, um festzustellen, wann die Freigabe von Zeilen aufgehoben wird. Dies ist beim Debuggen von Problemen bei der Zeilenfreigabe von Nutzen.
Um zu verhindern, dass die Freigabe von Zeilen aufgehoben wird, beachten Sie die folgenden Richtlinien:
Vermeiden Sie es, die Rows-Auflistung zu indizieren oder sie mit einer foreach-Schleife zu durchlaufen. Normalerweise müssen Sie nicht direkt auf Zeilen zugreifen. DataGridView-Methoden, die für Zeilen verwendet werden, verwenden anstelle von Zeileninstanzen die Argumente für den Zeilenindex. Darüber hinaus empfangen Handler für zeilenbezogene Ereignisse Ereignisargumentobjekte mit Zeileneigenschaften, die Sie zum Bearbeiten von Zeilen verwenden können, ohne dass dabei die Zeilenfreigabe aufgehoben wird.
Verwenden Sie die DataGridViewRowCollection.SharedRow-Methode, und übergeben Sie den tatsächlichen Index der Zeile, um auf ein Zeilenobjekt zuzugreifen. Beachten Sie jedoch, dass durch das Ändern eines freigegebenen Zeilenobjekts, das über diese Methode abgerufen wird, alle Zeilen geändert werden, die dieses Objekt gemeinsam nutzen. Die Zeile für neue Datensätze wird jedoch nicht mit anderen Zeilen freigegeben, sodass das Ändern anderer Zeilen sich nicht auf diese Zeile auswirkt. Beachten Sie auch, dass verschiedene, durch eine freigegebene Zeile dargestellte Zeilen über unterschiedliche Kontextmenüs verfügen können. Um das korrekte Kontextmenü von der Instanz einer freigegebenen Zeile abzurufen, verwenden Sie die GetContextMenuStrip-Methode und übergeben den tatsächlichen Index der Zeile. Falls Sie stattdessen auf die ContextMenuStrip-Eigenschaft der freigegebenen Zeile zugreifen, wird der Index -1 der freigegebenen Zeile verwendet und das falsche Kontextmenü abgerufen.
Vermeiden Sie es, die DataGridViewRow.Cells-Auflistung zu indizieren. Durch den direkten Zugriff auf eine Zelle wird die Freigabe der übergeordneten Zeile aufgehoben und eine neue DataGridViewRow instanziiert. Handler für zellenbezogene Ereignisse empfangen Ereignisargumentobjekte mit Zelleigenschaften, die Sie zum Bearbeiten von Zellen verwenden können, ohne dass dabei Zeilenfreigaben aufgehoben werden. Sie können auch mithilfe der CurrentCellAddress-Eigenschaft die Zeilen- und Spaltenindizes der aktuellen Zelle abrufen, ohne direkt auf die Zelle zuzugreifen.
Vermeiden Sie zellenbasierte Auswahlmodi. Diese Modi bewirken, dass Zeilenfreigaben aufgehoben werden. Legen Sie stattdessen die DataGridView.SelectionMode-Eigenschaft auf DataGridViewSelectionMode.FullRowSelect oder DataGridViewSelectionMode.FullColumnSelect fest.
Das DataGridViewRowCollection.CollectionChanged-Ereignis oder das DataGridView.RowStateChanged-Ereignis sollte nicht behandelt werden. Diese Ereignisse bewirken, dass Zeilenfreigaben aufgehoben werden. Vermeiden Sie es auch, die DataGridViewRowCollection.OnCollectionChanged-Methode oder die DataGridView.OnRowStateChanged-Methode aufzurufen, durch die diese Ereignisse ausgelöst werden.
Greifen Sie nicht auf die DataGridView.SelectedCells-Auflistung zu, wenn der Wert der DataGridView.SelectionMode-Eigenschaft FullColumnSelect, ColumnHeaderSelect, FullRowSelect oder RowHeaderSelect lautet. Dadurch wird die Freigabe aller ausgewählten Zeilen aufgehoben.
Rufen Sie nicht die DataGridView.AreAllCellsSelected-Methode auf. Diese Methode kann bewirken, dass Zeilenfreigaben aufgehoben werden.
Vermeiden Sie es, die DataGridView.SelectAll-Methode aufzurufen, wenn der Wert der DataGridView.SelectionMode-Eigenschaft CellSelect lautet. Dadurch wird die Freigabe aller Zeilen aufgehoben.
Legen Sie die ReadOnly-Eigenschaft oder Selected-Eigenschaft einer Zelle nicht auf false fest, wenn die entsprechende Eigenschaft in der zugehörigen Spalte auf true festgelegt ist. Dadurch wird die Freigabe aller Zeilen aufgehoben.
Greifen Sie nicht auf die DataGridViewRowCollection.List-Eigenschaft zu. Dadurch wird die Freigabe aller Zeilen aufgehoben.
Rufen Sie nicht die Sort(IComparer)-Überladung der Sort-Methode auf. Sortierungen mit einem benutzerdefinierten Vergleich führen dazu, dass die Freigabe sämtlicher Zeilen aufgehoben wird.
Siehe auch
Aufgaben
Konzepte
Virtueller Modus im DataGridView-Steuerelement in Windows Forms
Datenanzeigemodi im DataGridView-Steuerelement in Windows Forms
Zellstile im DataGridView-Steuerelement in Windows Forms
Größenänderungsoptionen im DataGridView-Steuerelement in Windows Forms
Referenz
Weitere Ressourcen
Leistungsoptimierung im DataGridView-Steuerelement in Windows Forms