Vue d’ensemble des panneaux personnalisés XAML

Un panneau est un objet qui fournit un comportement de disposition pour les éléments enfants qu’il contient, lorsque le système de disposition XAML (Extensible Application Markup Language) est exécuté et que l’interface utilisateur de votre application est affichée.

API importantes : Panel, ArrangeOverride, MeasureOverride

Vous pouvez définir des panneaux personnalisés pour la disposition XAML en dérivant une classe personnalisée à partir de la classe Panel. Vous fournissez le comportement pour votre panneau en substituant les méthodes MeasureOverride et ArrangeOverride et en fournissant la logique qui mesure et organise les éléments enfants.

Classe de base Panel

Pour définir une classe de panneau personnalisé, vous pouvez soit dériver directement de la classe Panel, soit dériver de l’une des classes de panneaux pratiques qui ne sont pas sealed, telles que Grid ou StackPanel. Il est plus facile de dériver de Panel, car il peut être difficile d’exploiter la logique de disposition existante d’un panneau qui possède déjà un comportement de disposition. De plus, un panneau avec un comportement peut avoir des propriétés existantes qui ne sont pas pertinentes pour les fonctionnalités de disposition de votre panneau.

À partir de Panel, votre panneau personnalisé hérite des API suivantes :

  • la propriété Children ;
  • les propriétés Background, ChildrenTransitions et IsItemsHost, ainsi que les identificateurs de propriétés de dépendances. Aucune de ces propriétés n’est virtuelle. Il n’est donc généralement pas nécessaire de les substituer ou de les remplacer. Elles ne sont la plupart du temps pas utiles pour les scénarios de panneau personnalisé, même pour la lecture de valeurs ;
  • Les méthodes de substitution de disposition MeasureOverride et ArrangeOverride. Elles ont été définies à l’origine par FrameworkElement. La classe Panel de base ne les substitue pas, mais des panneaux pratiques comme Grid ont des implémentations de substitution qui sont implémentées comme code natif et sont exécutées par le système. La fourniture d’implémentations nouvelles (ou additionnelles) pour ArrangeOverride et MeasureOverride constitue la plus grande partie de l’effort nécessaire pour définir un panneau personnalisé.
  • Toutes les autres API de FrameworkElement, UIElement et DependencyObject, telles que Height, Visibility et ainsi de suite. Vous pouvez parfois faire référence aux valeurs de ces propriétés dans vos substitutions de disposition, mais comme elles ne sont pas virtuelles, vous ne les substituez ou remplacez pas en règle générale.

L’objet ici est de décrire les concepts de disposition XAML pour que vous puissiez envisager toutes les possibilités de comportement d’un panneau personnalisé dans une disposition. Si vous préférez vous plonger tout de suite dans le cœur du sujet et examiner un exemple d’implémentation de panneau personnalisé, consultez l’article BoxPanel, exemple de panneau personnalisé.

Propriété Children

La propriété Children est pertinente lorsqu’il s’agit de panneau personnalisé, car toutes les classes dérivées de Panel utilisent la propriété Children comme emplacement de stockage de leurs éléments enfants dans une collection. Children est désignée comme propriété de contenu XAML pour la classe Panel et toutes les classes dérivées de Panel peuvent hériter du comportement de la propriété de contenu XAML. Si une propriété est désignée comme propriété de contenu XAML, cela signifie que le balisage XAML peut omettre un élément de propriété lors de la spécification de cette propriété dans le balisage et que les valeurs sont définies comme enfants de balisage immédiat (le « contenu »). Par exemple, si vous dérivez une classe nommée CustomPanel à partir de Panel qui ne définit aucun nouveau comportement, vous pouvez tout de même utiliser le balisage suivant :

<local:CustomPanel>
  <Button Name="button1"/>
  <Button Name="button2"/>
</local:CustomPanel>

Quand un analyseur XAML lit ce balisage, il sait que Children est la propriété de contenu XAML pour tous les types dérivés Panel. Il ajoute donc les deux éléments Button à la valeur UIElementCollection de la propriété Children. La propriété de contenu XAML facilite une relation parent-enfant rationalisée dans le balisage XAML pour une définition d’interface utilisateur. Pour plus d’informations sur les propriétés de contenu XAML et sur la manière dont les propriétés de collection sont renseignées lors de l’analyse du code XAML, voir le Guide sur la syntaxe XAML.

Le type de collection qui met à jour la valeur de la propriété Children est la classe UIElementCollection. UIElementCollection est une collection fortement typée qui utilise UIElement comme type d’élément appliqué. UIElement étant un type de base hérité par des centaines de types d’éléments d’interface utilisateur pratiques, l’application du type est ici délibérément libre. Toutefois, vous ne pourriez pas avoir un Brush comme enfant direct d’un Panel, ce qui signifie généralement que seuls les éléments censés être visibles dans l’interface utilisateur et participer à la disposition sont détectés comme éléments enfants dans un Panel.

En règle générale, un panneau personnalisé accepte n’importe quel élément enfant UIElement par une définition XAML, en utilisant simplement les caractéristiques de la propriété Children telle quelle. Dans un scénario avancé, vous pourriez prendre en charge une vérification supplémentaire du type des éléments enfants quand vous itérez au sein de la collection dans vos substitutions de disposition.

En plus de parcourir en boucle la collection Children dans les substitutions, votre logique de panneau peut aussi être influencée par Children.Count. Vous pourriez avoir une logique qui alloue de l’espace en se basant au moins en partie sur le nombre d’éléments plutôt que sur les tailles souhaitées et les autres caractéristiques des différents éléments.

Substitution des méthodes de disposition

Le modèle de base pour les méthodes de substitution de disposition (MeasureOverride et ArrangeOverride) est qu’elles doivent itérer au sein de tous les enfants et appeler la méthode de disposition spécifique à chaque élément enfant. Le premier cycle de disposition commence quand le système de disposition XAML définit les éléments visuels pour la fenêtre racine. Comme chaque parent appelle la disposition sur ses enfants, un appel aux méthodes de disposition est propagé à tous les éléments d’interface utilisateur possibles supposés faire partie d’une disposition. La disposition XAML comporte deux phases : la mesure, puis l’organisation.

Vous n’obtenez aucun comportement de méthode de disposition intégré pour MeasureOverride et ArrangeOverride à partir de la classe Panel de base. Les éléments Children ne sont pas affichés automatiquement dans le cadre de l’arborescence d’éléments visuels XAML. Vous devez faire en sorte que les éléments soient connus du processus de disposition en appelant des méthodes de disposition sur chacun des éléments que vous trouvez dans Children par l’intermédiaire d’une passe de disposition dans vos implémentations MeasureOverride et ArrangeOverride.

Il n’y a aucune raison d’appeler des implémentations de base dans des substitutions de disposition, sauf si vous disposez de votre propre héritage. Les méthodes natives pour le comportement de disposition (si elles existent) sont exécutées dans tous les cas et le fait de ne pas appeler l’implémentation de base à partir des substitutions n’empêchera pas le comportement natif de se produire.

Durant la passe de mesure, votre logique de disposition interroge chaque élément enfant pour connaître la taille souhaitée, en appelant la méthode Measure sur chacun d’eux. L’appel de la méthode Measure établit la valeur de la propriété DesiredSize. La valeur de retour de MeasureOverride est la taille souhaitée du panneau proprement dit.

Durant la passe d’organisation, les positions et tailles des éléments enfants sont déterminées dans l’espace x-y et la composition de la disposition est préparée en vue de l’affichage. Votre code doit appeler Arrange sur chaque élément enfant dans Children pour que le système de disposition détecte que l’élément appartient à la disposition. L’appel à Arrange est un précurseur de la composition et du rendu. Il informe le système de disposition de l’emplacement cible de l’élément, lorsque la composition est soumise en vue de l’affichage.

De nombreuses propriétés et valeurs contribuent au fonctionnement de la logique de disposition au moment de l’exécution. L’une des manières d’envisager le processus de disposition est de se dire que les éléments sans enfants (généralement ceux qui sont imbriqués le plus profondément dans l’interface utilisateur) sont ceux qui peuvent finaliser les mesures en premier. Ils n’ont pas de dépendance envers des éléments enfants qui influencent leur taille souhaitée. Ils peuvent avoir leurs propres tailles souhaitées, qui sont des suggestions de taille jusqu’à ce que la disposition ait réellement lieu. Ensuite, la passe de mesure continue à remonter l’arborescence d’éléments visuels jusqu’à ce que l’élément racine ait sa mesure et que toutes les mesures puissent être finalisées.

La disposition candidate doit être ajustée à la fenêtre d’application active, sinon certaines parties de l’interface utilisateur seront coupées. La logique de coupe est souvent déterminée au niveau des panneaux. La logique de panneau peut souvent déterminer la taille qui est disponible à partir de l’implémentation de MeasureOverride et peut devoir pousser les restrictions de taille vers les enfants et diviser l’espace parmi les enfants pour que tous les éléments soient ajustés du mieux possible. Le résultat de la disposition est, dans l’idéal, quelque chose qui utilise différentes propriétés de toutes les parties de la disposition tout en étant ajusté à la fenêtre de l’application. Cela nécessite à la fois une bonne implémentation de la logique de disposition des panneaux et une conception judicieuse de l’interface utilisateur de la part du code d’application qui génère une interface utilisateur à l’aide de ce panneau. Votre conception de panneau ne pourra pas être attrayante si la conception globale de l’interface utilisateur comporte plus d’éléments enfants que l’application ne peut en contenir.

Le bon fonctionnement du système de disposition est dû en grande partie au fait que tout élément basé sur FrameworkElement possède déjà une partie de son propre comportement inhérent quand il joue le rôle d’enfant dans un conteneur. Par exemple, il y a plusieurs API de FrameworkElement qui informent le comportement de disposition ou qui sont nécessaires au fonctionnement de la disposition. Ce sont, entre autres, les suivantes :

MeasureOverride

La méthode MeasureOverride a une valeur de retour qui est utilisée par le système de disposition comme DesiredSize de départ pour le panneau proprement dit, quand la méthode Measure est appelée sur le panneau par son parent dans la disposition. Les choix de logique dans la méthode sont tout aussi importants que les valeurs de retour et la logique influence souvent la valeur retournée.

Toutes les implémentations de MeasureOverride doivent parcourir Children en boucle et appeler la méthode Measure sur chaque élément enfant. L’appel de la méthode Measure établit la valeur de la propriété DesiredSize. Cela peut indiquer la quantité d’espace dont a besoin le panneau, ainsi que la manière dont cet espace est réparti parmi les éléments ou dimensionné pour un élément enfant spécifique.

Voici un squelette très rudimentaire de méthode MeasureOverride :

protected override Size MeasureOverride(Size availableSize)
{
    Size returnSize; //TODO might return availableSize, might do something else
     
    //loop through each Child, call Measure on each
    foreach (UIElement child in Children)
    {
        child.Measure(new Size()); // TODO determine how much space the panel allots for this child, that's what you pass to Measure
        Size childDesiredSize = child.DesiredSize; //TODO determine how the returned Size is influenced by each child's DesiredSize
        //TODO, logic if passed-in Size and net DesiredSize are different, does that matter?
    }
    return returnSize;
}

Les éléments ont souvent une taille naturelle au moment où ils sont prêts pour la disposition. Après la passe de mesure, la propriété DesiredSize peut indiquer cette taille naturelle, si la valeur availableSize que vous avez passée pourMeasure était plus petite. Si la taille naturelle est plus grande que la valeur availableSize que vous avez passée pour Measure, la propriété DesiredSize est limitée à availableSize. Tel est le comportement de l’implémentation interne de Measure, et vos substitutions de disposition doivent prendre ce comportement en compte.

Certains éléments n’ont pas de taille naturelle, car ils ont des valeurs Auto pour Height et Width. Ces éléments utiliseront la valeur availableSize entière, car c’est ce que représente une valeur Auto : dimensionner l’élément à la taille maximale disponible, que le parent de disposition immédiat communique en appelant Measure avec availableSize. En pratique, une interface utilisateur est toujours dimensionnée selon une certaine mesure (même s’il s’agit de la fenêtre de niveau supérieur). La passe de mesure finit par résoudre toutes les valeurs Auto aux contraintes parentes, et tous les éléments à valeur Auto obtiennent des mesures réelles (que vous pouvez obtenir en vérifiant ActualWidth et ActualHeight une fois la disposition terminée).

Vous pouvez passer une taille à Measure qui a au moins une dimension infinie pour indiquer que le panneau peut essayer de se dimensionner lui-même en fonction du contenu. Chaque élément enfant mesuré définit sa valeur DesiredSize en fonction de sa taille naturelle. Ensuite, durant la passe d’organisation, le panneau est généralement organisé avec cette taille.

Les éléments de texte tels que TextBlock ont des valeurs ActualWidth et ActualHeight calculées en fonction de leur chaîne de texte et propriétés de texte même si aucune valeur Height ou Width n’est définie, et ces dimensions doivent être respectées par la logique de votre panneau. Un texte tronqué est une expérience d’interface utilisateur particulièrement désagréable.

Même si votre implémentation n’utilise pas les mesures de taille souhaitée, il est préférable d’appeler la méthode Measure sur chaque élément enfant car certains comportements natifs et internes sont déclenchés par l’appel de Measure. Pour qu’un élément participe à la disposition, la méthode Measure doit être appelée sur chaque élément enfant durant la passe de mesure et la méthode Arrange doit être appelée durant la passe d’organisation. L’appel de ces méthodes définit des indicateurs internes sur l’objet et renseigne des valeurs (telles que la propriété DesiredSize) dont la logique de disposition du système a besoin quand elle génère l’arborescence d’éléments visuels et affiche l’interface utilisateur.

La valeur de retour de MeasureOverride est basée sur l’interprétation de la propriété DesiredSize par la logique du panneau ou par d’autres considérations de taille pour chacun des éléments enfants dans Children lorsque la méthode Measure est appelée sur eux. C’est l’interprétation de votre logique qui détermine ce qu’il faut faire avec les valeurs DesiredSize des enfants et comment la valeur de retour de MeasureOverride doit les utiliser. En règle générale, vous ne devez pas additionner les valeurs sans modification, car l’entrée de MeasureOverride est souvent une taille disponible fixe suggérée par le parent du panneau. Si vous dépassez cette taille, le panneau lui-même risque d’être coupé. Il faut généralement comparer la taille totale des enfants à la taille disponible du panneau et effectuer des ajustements si nécessaire.

Conseils et recommandations

  • Dans l’idéal, un panneau personnalisé doit convenir en tant que vrai premier élément visuel dans une composition d’interface utilisateur, par exemple à un niveau juste sous Page, UserControl ou un autre élément qui est la racine de la page XAML. Dans les implémentations de MeasureOverride, vous ne devez pas retourner systématiquement la valeur Size d’entrée sans examiner les valeurs. Si la valeur Size de retour contient une valeur Infinity, des exceptions risquent de se produire dans la logique de disposition au moment de l’exécution. Une valeur Infinity peut provenir de la fenêtre d’application principale, qui peut défiler et n’a donc pas de hauteur maximale. D’autres contenus avec défilement peuvent présenter le même comportement.
  • Une autre erreur courante dans les implémentations de MeasureOverride consiste à retourner une nouvelle valeur Size par défaut (les valeurs de hauteur et de largeur sont égales à 0). Vous pouvez commencer par cette valeur, et il peut même s’agir de la valeur correcte si votre panneau détermine qu’aucun des enfants ne doit être affiché. Mais avec une valeur Size par défaut, votre panneau n’est pas dimensionné correctement par son hôte. Il ne demande pas d’espace dans l’interface utilisateur, n’en obtient donc pas et n’est pas affiché. Tout le code de votre panneau fonctionne correctement, mais vous ne voyez pas votre panneau ou son contenu, car il est composé avec une hauteur et une largeur égales à 0.
  • Dans les substitutions, résistez à la tentation d’effectuer une conversion de type (transtypage) des éléments enfants vers FrameworkElement et d’utiliser des propriétés qui sont calculées suite à la disposition, en particulier ActualWidth et ActualHeight. Pour la plupart des scénarios courants, vous pouvez baser la logique sur la valeur DesiredSize de l’enfant, et vous n’avez pas besoin des propriétés en rapport avec Height ou Width d’un élément enfant. Pour les cas particuliers où vous connaissez le type d’élément et où vous possédez des informations supplémentaires, par exemple la taille naturelle d’un fichier image, vous pouvez utiliser ces informations spécifiques, car il ne s’agit pas d’une valeur modifiée de manière active par les systèmes de disposition. Le fait d’inclure des propriétés calculées par la disposition dans le cadre de la logique de disposition augmente de manière significative le risque de définir une boucle de disposition involontaire. Ces boucles provoquent une condition dans laquelle une disposition valide ne peut pas être créée et le système peut lever une exception LayoutCycleException si la boucle est irrécupérable.
  • Les panneaux répartissent en général leur espace disponible entre plusieurs éléments enfants, bien que la façon exacte dont l’espace est réparti varie. Par exemple, Grid implémente une logique de disposition qui utilise ses valeurs RowDefinition et ColumnDefinition pour diviser l’espace dans les cellules Grid, avec prise en charge à la fois des valeurs de pixels et de redimensionnement proportionnel. S’il s’agit de valeurs de pixels, la taille disponible pour chaque enfant est déjà connue. Elle est donc passée comme taille d’entrée pour une méthode Measure de style grille.
  • Les panneaux eux-mêmes peuvent introduire un espace réservé pour l’espacement entre les éléments. Dans ce cas, veillez à exposer les mesures en tant que propriété distincte de Margin ou de toute propriété Padding.
  • Des éléments peuvent avoir des valeurs pour leurs propriétés ActualWidth et ActualHeight basées sur une passe de disposition précédente. Si des valeurs changent, le code d’interface utilisateur de l’application peut placer des gestionnaires pour LayoutUpdated sur des éléments s’il y a une logique spéciale à exécuter, mais la logique de panneau n’a en général pas besoin de vérifier s’il y a des modifications avec la gestion des événements. Le système de disposition détermine déjà quand réexécuter la disposition car une propriété en rapport avec la disposition a changé de valeur et les méthodes MeasureOverride et ArrangeOverride d’un panneau sont appelées automatiquement dans les circonstances appropriées.

ArrangeOverride

La méthode ArrangeOverride a une valeur de retour Size qui est utilisée par le système de disposition lors de l’affichage du panneau proprement dit, quand la méthode Arrange est appelée sur le panneau par son parent dans la disposition. Il est courant que la valeur finalSize d’entrée et la valeur Size retournée par ArrangeOverride soient identiques. Si ce n’est pas le cas, cela veut dire que le panneau essaie de s’allouer une taille différente de celle déclarée comme disponible par les autres participants à la disposition. La taille finale est basée sur l’exécution précédente de la passe de mesure de disposition dans le code de panneau. C’est pourquoi le fait de retourner une taille différente n’est pas anodin : cela signifie que vous ignorez délibérément la logique de mesure.

Ne retournez pas une valeur Size avec un composant Infinity. L’utilisation d’une telle valeur Size lève une exception depuis la disposition interne.

Toutes les implémentations de ArrangeOverride doivent parcourir Children en boucle et appeler la méthode Arrange sur chaque élément enfant. Comme Measure, Arrange n’a pas de valeur de retour. Contrairement à Measure, aucune propriété calculée n’est définie en tant que résultat (toutefois, l’élément en question déclenche généralement un événement LayoutUpdated).

Voici un squelette très rudimentaire de méthode ArrangeOverride :

protected override Size ArrangeOverride(Size finalSize)
{
    //loop through each Child, call Arrange on each
    foreach (UIElement child in Children)
    {
        Point anchorPoint = new Point(); //TODO more logic for topleft corner placement in your panel
       // for this child, and based on finalSize or other internal state of your panel
        child.Arrange(new Rect(anchorPoint, child.DesiredSize)); //OR, set a different Size 
    }
    return finalSize; //OR, return a different Size, but that's rare
}

La passe d’organisation de disposition peut avoir lieu sans être précédée d’une passe de mesure. Cependant, cela ne se produit que lorsque le système de disposition a déterminé qu’aucune propriété n’ayant changé n’affecterait les mesures précédentes. Par exemple, si un alignement change, il est inutile de mesurer à nouveau cet élément spécifique car sa propriété DesiredSize ne changerait pas en cas de modification de son choix d’alignement. En revanche, si ActualHeight change sur un élément quelconque dans la disposition, une nouvelle passe de mesure est nécessaire. Le système de disposition détecte automatiquement les vrais changements de mesure et rappelle la passe de mesure, puis il exécute la passe d’organisation.

L’entrée de Arrange accepte une valeur Rect. Le moyen le plus répandu pour construire ce Rect consiste à utiliser le constructeur qui a une entrée Point et une entrée Size. Point est le point où l’angle supérieur gauche du cadre englobant pour l’élément doit être placé. Size correspond aux dimensions utilisées pour afficher cet élément spécifique. On utilise souvent la propriété DesiredSize de cet élément comme cette valeur Size, car l’établissement de la propriété DesiredSize pour tous les éléments impliqués dans la disposition était l’objectif de la passe de mesure de disposition. (La passe de mesure détermine le dimensionnement des éléments de manière itérative pour que le système de disposition puisse optimiser le placement des éléments une fois qu’il atteint la passe d’organisation.)

Ce qui varie en général entre les implémentations de ArrangeOverride, c’est la logique par laquelle le panneau détermine le composant Point pour l’organisation de chaque enfant. Un panneau de positionnement absolu tel que Canvasutilise les informations de placement explicites qu’il obtient à partir de chaque élément par l’intermédiaire des valeurs Canvas.Left et Canvas.Top. Un panneau de division de l’espace tel que Grid aurait des opérations mathématiques qui diviseraient l’espace disponible en cellules et chaque cellule aurait une valeur x-y indiquant où son contenu devrait être placé et organisé. Un panneau adaptatif tel que StackPanel pourrait s’étendre pour s’ajuster au contenu dans sa dimension d’orientation.

Il existe d’autres influences sur le positionnement des éléments dans la disposition, au-delà de ce que vous contrôlez directement et passez à Arrange. Ces influences proviennent de l’implémentation native interne de Arrange qui est commune à tous les types dérivés FrameworkElement et augmentée par d’autres types tels que les éléments de texte. Par exemple, des éléments peuvent avoir une marge et un alignement, tandis que d’autres peuvent avoir un espacement. Ces propriétés interagissent souvent. Pour plus d’informations, voir Alignement, marge et espacement.

Panneaux et contrôles

Évitez de placer dans un panneau une fonctionnalité qui devrait plutôt être générée en tant que contrôle personnalisé. Le rôle d’un panneau consiste à présenter tout contenu d’élément enfant qui existe à l’intérieur du panneau, en tant que fonction de disposition qui se produit automatiquement. Le panneau peut ajouter des décorations au contenu (un peu comme un objet Border ajoute la bordure autour de l’élément qu’il présente) ou effectuer d’autres ajustements liés à la disposition (comme l’espacement). Mais vous ne devez pas aller plus loin lors de l’extension de la sortie de l’arborescence d’éléments visuels au-delà du signalement et de l’utilisation d’informations provenant des enfants.

Si une interaction est accessible à l’utilisateur, vous devez écrire un contrôle personnalisé, et non un panneau. Par exemple, un panneau ne doit pas ajouter de fenêtres d’affichage de défilement à du contenu qu’il présente, même si l’objectif est d’empêcher la troncature du texte, car les barres de défilement, pouces et autres sont des parties de contrôle interactives. (Le contenu peut avoir des barres de défilement après tout, mais vous devez laisser cela à la logique de l’enfant. Ne la forcez pas en ajoutant le défilement en tant qu’opération de disposition.) Vous pouvez créer un contrôle et écrire un panneau personnalisé qui joue un rôle important dans l’arborescence visuelle de ce contrôle, quand il s’agit de présenter du contenu dans ce contrôle. mais le contrôle et le panneau doivent être des objets de code distincts.

Cette distinction entre un contrôle et un panneau est importante en raison de l’accessibilité et de Microsoft UI Automation. Les panneaux fournissent un comportement de disposition visuelle, et non un comportement logique. La manière dont un élément d’interface utilisateur apparaît visuellement n’est pas un aspect de l’interface utilisateur qui est en général important dans les scénarios d’accessibilité. L’accessibilité s’intéresse à l’affichage des parties d’une application qui sont importantes pour comprendre une interface utilisateur. Lorsqu’une interaction est nécessaire, les contrôles doivent exposer les possibilités d’interaction à l’infrastructure UI Automation. Pour plus d’informations, voir Homologues d’automation personnalisés.

Autres API de disposition

D’autres API font partie du système de disposition mais ne sont pas déclarées par Panel. Vous pouvez les utiliser dans une implémentation de panneau ou dans un contrôle personnalisé qui utilise des panneaux.

  • UpdateLayout, InvalidateMeasure et InvalidateArrange sont des méthodes qui initient une passe de disposition. InvalidateArrange peut ne pas déclencher de passe de mesure, mais les deux autres en déclenchent une. N’appelez jamais ces méthodes à partir d’une substitution de méthode de disposition, car elles provoqueront presque à coup sûr une boucle de disposition. Le code de contrôle n’a généralement pas besoin de les appeler non plus. La plupart des aspects de la disposition sont déclenchés automatiquement grâce à la détection des modifications apportées aux propriétés de disposition définies par l’infrastructure, telles que Width et ainsi de suite.
  • LayoutUpdated est un événement déclenché lorsqu'un aspect de disposition de l'élément a changé. Cela n’est pas spécifique aux panneaux ; l’événement est défini par FrameworkElement.
  • SizeChanged est un événement déclenché seulement une fois que les passes de disposition ont été finalisées. Il indique que ActualHeight ou ActualWidth a changé en conséquence. Il s’agit d’un autre événement FrameworkElement. Dans certains cas, LayoutUpdated se déclenche, mais pas SizeChanged. Par exemple, le contenu interne peut être réorganisé, mais la taille de l’élément n’a pas changé.

Informations de référence

Concepts