Optimisation des performances : liaison de donnéesOptimizing Performance: Data Binding

La liaison de données Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) offre un moyen simple et cohérent pour les applications de présenter les données et d’interagir avec elles.Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding provides a simple and consistent way for applications to present and interact with data. Les éléments peuvent être liés à des données provenant de diverses sources de données sous la forme d’objets CLR et XML.Elements can be bound to data from a variety of data sources in the form of CLR objects and XML.

Cette rubrique fournit des recommandations sur les performances de la liaison de données.This topic provides data binding performance recommendations.

Comment les références de liaison de données sont résoluesHow Data Binding References are Resolved

Avant d’aborder les problèmes de performances de la liaison de données, il est utile d’explorer la façon dont le moteur de liaison de données Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) résout les références d’objet pour la liaison.Before discussing data binding performance issues, it is worthwhile to explore how the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding engine resolves object references for binding.

La source d’une liaison de données Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) peut être n’importe quel objet CLR.The source of a Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding can be any CLR object. Vous pouvez lier des propriétés, des sous-propriétés ou des indexeurs d’un objet CLR.You can bind to properties, sub-properties, or indexers of a CLR object. Les références de liaison sont résolues à l’aide de la réflexion Microsoft .NET Framework ou d’une ICustomTypeDescriptor.The binding references are resolved by using either Microsoft .NET Framework reflection or an ICustomTypeDescriptor. Voici trois méthodes permettant de résoudre les références d’objet pour la liaison.Here are three methods for resolving object references for binding.

La première méthode repose sur l’utilisation de la réflexion.The first method involves using reflection. Dans ce cas, l’objet PropertyInfo est utilisé pour découvrir les attributs de la propriété et fournit l’accès aux métadonnées de propriété.In this case, the PropertyInfo object is used to discover the attributes of the property and provides access to property metadata. Lors de l’utilisation de l’interface ICustomTypeDescriptor, le moteur de liaison de données utilise cette interface pour accéder aux valeurs de propriété.When using the ICustomTypeDescriptor interface, the data binding engine uses this interface to access the property values. L’interface ICustomTypeDescriptor est particulièrement utile dans les cas où l’objet n’a pas d’ensemble statique de propriétés.The ICustomTypeDescriptor interface is especially useful in cases where the object does not have a static set of properties.

Les notifications de modification de propriété peuvent être fournies soit en implémentant l’interface INotifyPropertyChanged, soit en utilisant les notifications de modification associées à l' TypeDescriptor.Property change notifications can be provided either by implementing the INotifyPropertyChanged interface or by using the change notifications associated with the TypeDescriptor. Toutefois, la stratégie par défaut pour l’implémentation des notifications de modification de propriété consiste à utiliser INotifyPropertyChanged.However, the preferred strategy for implementing property change notifications is to use INotifyPropertyChanged.

Si l’objet source est un objet CLR et que la propriété source est une propriété CLR, le moteur de liaison de données Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) doit d’abord utiliser la réflexion sur l’objet source pour obtenir le TypeDescriptor, puis interroger un PropertyDescriptor.If the source object is a CLR object and the source property is a CLR property, the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding engine has to first use reflection on the source object to get the TypeDescriptor, and then query for a PropertyDescriptor. Cette séquence d’opérations de réflexion peut s’avérer très fastidieuse du point de vue des performances.This sequence of reflection operations is potentially very time-consuming from a performance perspective.

La deuxième méthode de résolution des références d’objet implique un objet CLR source qui implémente l’interface INotifyPropertyChanged et une propriété source qui est une propriété CLR.The second method for resolving object references involves a CLR source object that implements the INotifyPropertyChanged interface, and a source property that is a CLR property. Dans ce cas, le moteur de liaison de données applique la réflexion directement au type de source et obtient la propriété nécessaire.In this case, the data binding engine uses reflection directly on the source type and gets the required property. Ce n’est toujours pas la méthode optimale, mais elle est moins exigeante que la première méthode en termes de spécifications de la plage de travail.This is still not the optimal method, but it will cost less in working set requirements than the first method.

La troisième méthode pour résoudre les références d’objet implique un objet source qui est un DependencyObject et une propriété source qui est un DependencyProperty.The third method for resolving object references involves a source object that is a DependencyObject and a source property that is a DependencyProperty. Dans ce cas, le moteur de liaison de données n’a pas besoin d’utiliser la réflexion.In this case, the data binding engine does not need to use reflection. Au lieu de cela, le moteur de propriété et le moteur de liaison de données résolvent ensemble la référence de propriété de manière indépendante.Instead, the property engine and the data binding engine together resolve the property reference independently. Il s’agit de la méthode optimale pour résoudre les références d’objet utilisées pour la liaison de données.This is the optimal method for resolving object references used for data binding.

Le tableau ci-dessous compare la vitesse de liaison de données à la propriété Text de 1000 TextBlock éléments à l’aide de ces trois méthodes.The table below compares the speed of data binding the Text property of one thousand TextBlock elements using these three methods.

Liaison de la propriété Text d’un TextBloxBinding the Text property of a TextBlock Temps de liaison (ms)Binding time (ms) Temps de rendu -- liaison incluse (ms)Render time -- includes binding (ms)
À une propriété d’un objet CLRTo a property of a CLR object 115115 314314
À une propriété d’un objet CLR qui implémente INotifyPropertyChangedTo a property of a CLR object which implements INotifyPropertyChanged 115115 305305
À un DependencyProperty d’un DependencyObject.To a DependencyProperty of a DependencyObject. 9090 263263

Liaison à des objets CLR volumineuxBinding to Large CLR Objects

Il y a un impact significatif sur les performances lorsque vous liez des données à un objet CLR unique avec des milliers de propriétés.There is a significant performance impact when you data bind to a single CLR object with thousands of properties. Vous pouvez réduire cet impact en divisant l’objet unique en plusieurs objets CLR avec moins de propriétés.You can minimize this impact by dividing the single object into multiple CLR objects with fewer properties. Le tableau indique les temps de liaison et de rendu pour la liaison de données à un seul objet CLR de grande taille par rapport à plusieurs objets plus petits.The table shows the binding and rendering times for data binding to a single large CLR object versus multiple smaller objects.

Liaison de données de 1 000 objets TextBlockData binding 1000 TextBlock objects Temps de liaison (ms)Binding time (ms) Temps de rendu -- liaison incluse (ms)Render time -- includes binding (ms)
À un objet CLR avec des propriétés 1000To a CLR object with 1000 properties 950950 12001200
Pour 1000 objets CLR avec une propriétéTo 1000 CLR objects with one property 115115 314314

Liaison à un ItemsSourceBinding to an ItemsSource

Imaginez un scénario dans lequel vous avez un objet CLR List<T> qui contient une liste d’employés que vous souhaitez afficher dans une ListBox.Consider a scenario in which you have a CLR List<T> object that holds a list of employees that you want to display in a ListBox. Pour créer une correspondance entre ces deux objets, vous devez lier votre liste d’employés à la propriété ItemsSource du ListBox.To create a correspondence between these two objects, you would bind your employee list to the ItemsSource property of the ListBox. Or, il se trouve qu’un nouvel employé rejoint le groupe.However, suppose you have a new employee joining your group. Vous pensez peut-être que pour insérer cette nouvelle personne dans vos valeurs de ListBox liées, il vous suffit d’ajouter cette personne à votre liste d’employés et de vous attendre à ce que cette modification soit reconnue automatiquement par le moteur de liaison de données.You might think that in order to insert this new person into your bound ListBox values, you would simply add this person to your employee list and expect this change to be recognized by the data binding engine automatically. Cette hypothèse s’est avérée fausse. en réalité, la modification ne sera pas reflétée automatiquement dans la ListBox.That assumption would prove false; in actuality, the change will not be reflected in the ListBox automatically. Cela est dû au fait que l’objet List<T> CLR ne déclenche pas automatiquement un événement de modification de collection.This is because the CLR List<T> object does not automatically raise a collection changed event. Pour que les ListBox récupèrent les modifications, vous devez recréer votre liste d’employés et la rattacher à la propriété ItemsSource de l' ListBox.In order to get the ListBox to pick up the changes, you would have to recreate your list of employees and re-attach it to the ItemsSource property of the ListBox. Bien que cette solution fonctionne, elle a un fort impact sur les performances.While this solution works, it introduces a huge performance impact. Chaque fois que vous réaffectez la ItemsSource de ListBox à un nouvel objet, le ListBox rejette d’abord ses éléments précédents et régénère la liste entière.Each time you reassign the ItemsSource of ListBox to a new object, the ListBox first throws away its previous items and regenerates its entire list. L’impact sur les performances est accru si votre ListBox est mappée à un DataTemplatecomplexe.The performance impact is magnified if your ListBox maps to a complex DataTemplate.

Une solution très efficace à ce problème consiste à faire de votre employé une liste de ObservableCollection<T>.A very efficient solution to this problem is to make your employee list an ObservableCollection<T>. Un objet ObservableCollection<T> déclenche une notification de modification que le moteur de liaison de données peut recevoir.An ObservableCollection<T> object raises a change notification which the data binding engine can receive. L’événement ajoute ou supprime un élément d’un ItemsControl sans qu’il soit nécessaire de régénérer la liste entière.The event adds or removes an item from an ItemsControl without the need to regenerate the entire list.

Le tableau ci-dessous indique le temps nécessaire pour mettre à jour le ListBox (avec la virtualisation de l’interface utilisateur désactivée) lorsqu’un élément est ajouté.The table below shows the time it takes to update the ListBox (with UI virtualization turned off) when one item is added. Le nombre de la première ligne représente le temps écoulé lorsque l’objet List<T> CLR est lié au ItemsSourcede ListBox élément.The number in the first row represents the elapsed time when the CLR List<T> object is bound to ListBox element's ItemsSource. Le nombre de la deuxième ligne représente le temps écoulé quand un ObservableCollection<T> est lié au ItemsSourcede l’élément de ListBox.The number in the second row represents the elapsed time when an ObservableCollection<T> is bound to the ListBox element's ItemsSource. Notez les gains de temps significatifs à l’aide de la stratégie de liaison de données ObservableCollection<T>.Note the significant time savings using the ObservableCollection<T> data binding strategy.

Liaison de données de la propriété ItemsSourceData binding the ItemsSource Temps de mise à jour pour 1 élément (ms)Update time for 1 item (ms)
À un objet de List<T> CLRTo a CLR List<T> object 1 6561656
À une ObservableCollection<T>To an ObservableCollection<T> 2020

Lier un objet IList à un objet ItemsControl non IEnumerableBind IList to ItemsControl not IEnumerable

Si vous avez le choix entre la liaison d’un IList<T> ou d’un IEnumerable à un objet ItemsControl, choisissez l’objet IList<T>.If you have a choice between binding an IList<T> or an IEnumerable to an ItemsControl object, choose the IList<T> object. La liaison de IEnumerable à un ItemsControl force WPFWPF à créer un wrapper IList<T> objet, ce qui signifie que vos performances sont affectées par la surcharge inutile d’un deuxième objet.Binding IEnumerable to an ItemsControl forces WPFWPF to create a wrapper IList<T> object, which means your performance is impacted by the unnecessary overhead of a second object.

Ne convertissez pas des objets CLR en XML seulement à des fins de liaison de données.Do not Convert CLR objects to XML Just for Data Binding.

WPFWPF vous permet de lier des données à du contenu XML ; Toutefois, la liaison de données au contenu XML est plus lente que la liaison de données aux objets CLR.allows you to data bind to XML content; however, data binding to XML content is slower than data binding to CLR objects. Ne convertissez pas les données d’objet CLR en XML si le seul objectif est de lier les données.Do not convert CLR object data to XML if the only purpose is for data binding.

Voir aussiSee also