(0) exportieren Drucken
Alle erweitern

Optimieren der Leistung: Datenbindung

Aktualisiert: November 2007

Die Windows Presentation Foundation (WPF)-Datenbindung bietet für Anwendungen eine einfache und konsistente Möglichkeit, Daten darzustellen und mit ihnen zu interagieren. Elemente können an Daten aus einer Vielzahl von Datenquellen in Form von CLR-Objekten und XML gebunden werden.

Dieses Thema enthält Empfehlungen zur Leistungssteigerung bei der Datenbindung.

Dieses Thema enthält folgende Abschnitte.

Bevor Leistungsfragen der Datenbindung erläutert werden, lohnt es sich zu untersuchen, wie das Windows Presentation Foundation (WPF)-Datenbindungsmodul Objektverweise für die Bindung auflöst.

Die Quelle einer Windows Presentation Foundation (WPF)-Datenbindung kann ein beliebiges CLR-Objekt sein. Die Bindung kann an Eigenschaften, Untereigenschaften oder Indexer eines CLR-Objekts erfolgen. Die Bindungsverweise werden mit Microsoft .NET Framework-Reflektion oder einem ICustomTypeDescriptor aufgelöst. Im Folgenden finden Sie drei Methoden zum Auflösen von Objektverweisen zur Bindung.

Die erste Methode verwendet dazu Reflektion. In diesem Fall werden mit dem PropertyInfo-Objekt die Attribute der Eigenschaft ermittelt. Dieses Objekt bietet auch Zugriff auf die Metadaten der Eigenschaft. Wenn die ICustomTypeDescriptor-Schnittstelle verwendet wird, greift das Datenbindungsmodul mithilfe dieser Schnittstelle auf die Eigenschaftenwerte zu. Die ICustomTypeDescriptor-Schnittstelle ist insbesondere in Fällen hilfreich, bei denen das Objekt nicht über einen statischen Eigenschaftensatz verfügt.

Benachrichtigungen über Eigenschaftenänderungen können durch Implementierung der INotifyPropertyChanged-Schnittstelle oder durch Verwendung der dem TypeDescriptor zugeordneten Änderungsbenachrichtigungen bereitgestellt werden. Die bevorzugte Strategie zur Implementierung von Benachrichtigungen über Eigenschaftenänderungen ist aber die Verwendung von INotifyPropertyChanged.

Wenn das Quellobjekt ein CLR-Objekt und die Quelleigenschaft eine CLR-Eigenschaft ist, muss das Windows Presentation Foundation (WPF)-Datenbindungsmodul für das Quellobjekt zuerst Reflektion verwenden, um den TypeDescriptor abzurufen, und dann einen PropertyDescriptor abfragen. Unter Leistungsaspekten ist diese Abfolge von Reflektionsvorgängen unter Umständen äußerst zeitaufwändig.

Die zweite Methode zum Auflösen von Objektverweisen verwendet ein CLR-Quellobjekt, das die INotifyPropertyChanged-Schnittstelle implementiert, und eine Quelleigenschaft, bei der es sich um eine CLR-Eigenschaft handelt. In diesem Fall verwendet das Datenbindungsmodul Reflektion direkt für den Quelltyp und ruft die benötigte Eigenschaft ab. Hierbei handelt es sich immer noch nicht um die optimale Methode, sie kommt aber mit weniger Anforderungen an das Workingset aus als die erste Methode.

Die dritte Methode zum Auflösen von Objektverweisen verwendet ein Quellobjekt, das ein DependencyObject ist, und eine Quelleigenschaft, die eine DependencyProperty ist. In diesem Fall muss das Datenbindungsmodul keine Reflektion verwenden. Stattdessen lösen das Eigenschaftenmodul und das Datenbindungsmodul den Eigenschaftenverweis unabhängig voneinander auf. Dies ist die optimale Methode zum Auflösen von Objektverweisen, die zur Datenbindung verwendet werden.

In der Tabelle unten wird die Geschwindigkeit der Datenbindung der Text-Eigenschaft von eintausend TextBlock-Elementen bei Verwendung der drei Methoden verglichen.

Binden der Text-Eigenschaft von TextBlock

Bindungszeit (ms)

Zeit zum Rendern - inklusive Bindung (ms)

An eine Eigenschaft eines CLR-Objekts

115

314

An eine Eigenschaft eines CLR-Objekts, das INotifyPropertyChanged implementiert

115

305

An eine DependencyProperty von einem DependencyObject.

90

263

Die Auswirkungen auf die Leistung sind beträchtlich, wenn die Datenbindung an ein einzelnes CLR-Objekt mit tausenden von Eigenschaften ausgeführt wird. Sie können diese Auswirkung minimieren, indem Sie das einzelne Objekt in mehrere CLR-Objekte mit weniger Eigenschaften aufteilen. Die Tabelle enthält die Zeiten für Bindung und Rendern bei der Datenbindung an ein einzelnes großes CLR-Objekt im Vergleich zur Bindung an mehrere kleinere Objekte.

Datenbindung von 1000 TextBlock-Objekten

Bindungszeit (ms)

Zeit zum Rendern - inklusive Bindung (ms)

An ein CLR-Objekt mit 1000 Eigenschaften

950

1200

An 1000 CLR-Objekte mit einer Eigenschaft

115

314

Angenommen, es gibt ein CLRList<T>-Objekt mit einer Liste von Angestellten, die Sie in einem ListBox anzeigen möchten. Um eine Entsprechung zwischen diesen beiden Objekten herzustellen, binden Sie die Angestelltenliste an die ItemsSource-Eigenschaft für das ListBox. Aber jetzt gibt es einen neuen Mitarbeiter in der Gruppe. Möglicherweise gehen Sie davon aus, dass es ausreicht, diese neue Person einfach zur Angestelltenliste hinzuzufügen, um die Person in die gebundenen ListBox-Werte einzufügen, und dass diese Änderung automatisch vom Datenbindungsmodul erkannt wird. Diese Annahme würde sich als falsch erweisen. In Wirklichkeit wird die Änderung nicht automatisch im ListBox reflektiert. Der Grund dafür ist, dass das CLR, List<T>-Objekt nicht automatisch ein Ereignis für eine geänderte Auflistung auslöst. Damit das ListBox die Änderungen übernimmt, müssten Sie die Angestelltenliste erneut erstellen und sie der ItemsSource-Eigenschaft des ListBox wieder anfügen. Die Lösung funktioniert zwar, hat aber enorme Auswirkungen auf die Leistung. Jedes Mal, wenn Sie einem neuen Objekt die ItemsSource von ListBox wieder zuordnen, entfernt das ListBox zunächst die bisherigen Elemente und generiert die gesamte Liste neu. Die Auswirkungen auf die Leistung werden noch größer, wenn das ListBox einer komplexen DataTemplate zugeordnet wird.

Eine sehr effiziente Lösung für dieses Problem ist es, die Angestelltenliste zu einer ObservableCollection<T> zu machen. Ein ObservableCollection<T>-Objekt löst eine Änderungsbenachrichtigung aus, die das Datenbindungsmodul empfangen kann. Das Ereignis fügt einem ItemsControl ein Element hinzu bzw. entfernt es daraus, ohne dass die gesamte Liste neu generiert werden muss.

In der unten stehenden Tabelle wird die benötigte Zeit angezeigt, um das ListBox zu aktualisieren (bei deaktivierter Virtualisierung der Benutzeroberfläche), wenn ein Element hinzugefügt wird. Die Zahl in der ersten Zeile gibt die verstrichene Zeit an, wenn das CLR-List<T>-Objekt an ItemsSource des ListBox-Elements gebunden wird. Die Zahl in der zweiten Zeile gibt die verstrichene Zeit an, wenn eine ObservableCollection<T> an die ItemsSource des ListBox-Elements gebunden wird. Beachten Sie die immense Zeitersparnis, wenn die Datenbindungsstrategie von ObservableCollection<T> verwendet wird.

Datenbindung von ItemsSource

Aktualisierungszeit für 1 Element (ms)

An ein CLRList<T>-Objekt

1656

An eine ObservableCollection<T>

20

Wenn Sie auswählen können, IList<T> oder IEnumerable an ein ItemsControl-Objekt zu binden, entscheiden Sie sich für das IList<T>-Objekt. Wenn Sie IEnumerable an ItemsControl binden, wird erzwungen, dass WPF ein IList<T>-Wrapperobjekt erstellt, was bedeutet, dass der unnötige Verwaltungsaufwand eines zweiten Objekts sich auf die Leistung auswirkt.

Mit WPF können Sie die Datenbindung an XML-Inhalte ausführen. Allerdings ist die Datenbindung an XML-Inhalte langsamer als die Datenbindung an CLR-Objekte. Konvertieren Sie keine CLR-Objektdaten in XML, wenn es nur zum Zwecke der Datenbindung geschieht.

Community-Beiträge

HINZUFÜGEN
Anzeigen:
© 2014 Microsoft