Partager via


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) s’exécute et que l’interface utilisateur de votre application est rendue.

API importantes : Panel, ArrangeOverride, MeasureOverride

Vous pouvez définir des panneaux personnalisés pour la disposition XAML en dérivant une classe personnalisée de la classe Panel. Vous fournissez un comportement pour votre panneau en remplaçant MeasureOverride et ArrangeOverride, en fournissant une logique qui mesure et organise les éléments enfants.

Classe de base panel

Pour définir une classe de panneau personnalisée, vous pouvez dériver directement de la classe Panel ou dériver de l’une des classes de panneau pratiques qui ne sont pas scellées, telles que Grid ou StackPanel. Il est plus facile de dériver du panneau, car il peut être difficile de contourner la logique de disposition existante d’un panneau qui a déjà un comportement de disposition. En outre, un panneau avec comportement peut avoir des propriétés existantes qui ne sont pas pertinentes pour les fonctionnalités de disposition de votre panneau.

À partir du panneau, votre panneau personnalisé hérite de ces API :

  • Propriété Children .
  • Propriétés Background, ChildrenTransitions et IsItemsHost et identificateurs de propriété de dépendance. Aucune de ces propriétés n’est virtuelle. Vous ne les remplacez généralement pas ou ne les remplacez pas. Vous n’avez généralement pas besoin de ces propriétés pour les scénarios de panneau personnalisés, pas même pour la lecture de valeurs.
  • Méthodes de remplacement de disposition MeasureOverride et ArrangeOverride. Celles-ci ont été définies à l’origine par FrameworkElement. La classe panneau de base ne les remplace pas, mais les panneaux pratiques tels que Grid ont des implémentations de remplacement implémentées en tant que code natif et sont exécutées par le système. La fourniture de nouvelles implémentations (ou additifs) pour ArrangeOverride et MeasureOverride est l’essentiel de l’effort que vous devez définir un panneau personnalisé.
  • Toutes les autres API de FrameworkElement, UIElement et DependencyObject, telles que Height, Visibility, etc. Vous référencez parfois les valeurs de ces propriétés dans vos remplacements de disposition, mais elles ne sont pas virtuelles, de sorte que vous ne les remplacez généralement pas ou les remplacez.

Ce focus est ici pour décrire les concepts de disposition XAML, de sorte que vous pouvez prendre en compte toutes les possibilités pour la façon dont un panneau personnalisé peut et doit se comporter dans la disposition. Si vous préférez vous lancer directement et voir un exemple d’implémentation de panneau personnalisé, consultez BoxPanel, un exemple de panneau personnalisé.

Propriété Children

La propriété Children est pertinente pour un panneau personnalisé, car toutes les classes dérivées du panneau utilisent la propriété Children comme emplacement pour stocker leurs éléments enfants contenus dans une collection. Les enfants sont désignés 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 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 en tant qu’enfants de balisage immédiat (le « contenu »). Par exemple, si vous dérivez une classe nommée CustomPanel à partir du panneau qui ne définit aucun nouveau comportement, vous pouvez toujours utiliser ce balisage :

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

Lorsqu’un analyseur XAML lit ce balisage, Children est connu comme la propriété de contenu XAML pour tous les types dérivés du panneau. Par conséquent, l’analyseur ajoute 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 façon dont les propriétés de collection sont remplies lorsque XAML est analysé, consultez le guide de syntaxe XAML.

Le type de collection qui conserve 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 est un type de base hérité par des centaines de types d’éléments d’interface utilisateur pratiques. L’application du type est donc délibérément lâche. Mais il applique que vous n’avez pas pu avoir un pinceau en tant qu’enfant direct d’un panneau, et cela signifie généralement que seuls les éléments qui sont censés être visibles dans l’interface utilisateur et participer à la disposition sont trouvés en tant qu’éléments enfants dans un panneau.

En règle générale, un panneau personnalisé accepte tout élément enfant UIElement par une définition XAML, en utilisant simplement les caractéristiques de la propriété Children en l’état. En tant que scénario avancé, vous pouvez prendre en charge la vérification de type supplémentaire des éléments enfants lorsque vous effectuez une itération sur la collection dans vos remplacements de disposition.

Outre la boucle dans la collection Children dans les remplacements, votre logique de panneau peut également être influencée par Children.Count. Vous pouvez avoir une logique qui alloue de l’espace au moins en partie en fonction du nombre d’éléments, plutôt que des tailles souhaitées et des autres caractéristiques d’éléments individuels.

Substitution des méthodes de disposition

Le modèle de base pour les méthodes de remplacement de disposition (MeasureOverride et ArrangeOverride) est qu’ils doivent itérer à travers tous les enfants et appeler la méthode de disposition spécifique de chaque élément enfant. Le premier cycle de disposition commence lorsque le système de disposition XAML définit le visuel de la fenêtre racine. Étant donné que chaque parent appelle la disposition sur ses enfants, cela propage un appel aux méthodes de disposition à chaque élément d’interface utilisateur possible censé faire partie d’une disposition. Dans la disposition XAML, il existe deux étapes : la mesure, puis l’organiser.

Vous n’obtenez aucun comportement de méthode de disposition intégrée pour MeasureOverride et ArrangeOverride à partir de la classe panneau de base. Les éléments des enfants ne s’affichent pas automatiquement dans l’arborescence visuelle XAML. Il vous incombe de faire connaître les éléments du processus de disposition en appelant les méthodes de disposition sur chacun des éléments que vous trouvez dans Children via une passe de disposition dans vos implémentations MeasureOverride et ArrangeOverride.

Il n’existe aucune raison d’appeler des implémentations de base dans les remplacements de disposition, sauf si vous avez votre propre héritage. Les méthodes natives pour le comportement de disposition (s’ils existent) s’exécutent indépendamment et n’appellent pas l’implémentation de base des substitutions n’empêche pas le comportement natif de se produire.

Pendant la passe de mesure, votre logique de disposition interroge chaque élément enfant pour sa taille souhaitée, en appelant la méthode Measure sur cet élément enfant. L’appel de la méthode Measure établit la valeur de la propriété DesiredSize. La valeur de retour MeasureOverride est la taille souhaitée pour le panneau lui-même.

Pendant la passe d’organisation, les positions et les tailles des éléments enfants sont déterminées dans l’espace x-y et la composition de disposition est préparée pour le rendu. Votre code doit appeler Arrange sur chaque élément enfant dans Children afin 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 où cet élément est envoyé, lorsque la composition est envoyée pour le rendu.

De nombreuses propriétés et valeurs contribuent à la façon dont la logique de disposition fonctionnera au moment de l’exécution. Un moyen de réfléchir au processus de disposition est que les éléments sans enfants (généralement l’élément le plus profondément imbriqué dans l’interface utilisateur) sont ceux qui peuvent finaliser les mesures en premier. Ils n’ont aucune dépendance sur les éléments enfants qui influencent leur taille souhaitée. Ils peuvent avoir leurs propres tailles souhaitées, et ce sont des suggestions de taille jusqu’à ce que la disposition ait réellement lieu. Ensuite, la passe de mesure continue à parcourir l’arborescence visuelle jusqu’à ce que l’élément racine ait ses mesures et que toutes les mesures puissent être finalisées.

La disposition candidate doit s’adapter à la fenêtre d’application actuelle ou à d’autres parties de l’interface utilisateur seront découpées. Les panneaux sont souvent l’endroit où la logique de découpage est déterminée. La logique du panneau peut déterminer la taille disponible à partir de l’implémentation MeasureOverride et peut avoir à pousser les restrictions de taille sur les enfants et à diviser l’espace entre les enfants afin que tout s’adapte le mieux possible. Le résultat de la disposition est idéalement un élément qui utilise différentes propriétés de toutes les parties de la disposition, mais qui s’inscrit toujours dans la fenêtre de l’application. Cela nécessite une bonne implémentation pour la logique de disposition des panneaux, ainsi qu’une conception d’interface utilisateur judicieuse dans le cadre de tout code d’application qui génère une interface utilisateur à l’aide de ce panneau. Aucune conception de panneau ne va ressembler si la conception globale de l’interface utilisateur inclut plus d’éléments enfants que possible dans l’application.

Une grande partie de ce qui rend le système de disposition fonctionne est que tout élément basé sur FrameworkElement a déjà un comportement inhérent lors de l’action en tant qu’enfant dans un conteneur. Par exemple, il existe plusieurs API de FrameworkElement qui informent le comportement de disposition ou sont nécessaires pour que la disposition fonctionne. Il s’agit notamment des paramètres suivants :

MeasureOverride

La méthode MeasureOverride a une valeur de retour utilisée par le système de disposition comme desiredSize de départ pour le panneau lui-même, lorsque la méthode Measure est appelée sur le panneau par son parent dans la disposition. Les choix logiques au sein de la méthode sont tout aussi importants que ce qu’il retourne, et la logique influence souvent la valeur retournée.

Toutes les implémentations MeasureOverride doivent effectuer une boucle dans Children 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 combien d’espace le panneau lui-même a besoin, ainsi que la façon dont cet espace est divisé entre les éléments ou dimensionné pour un élément enfant particulier.

Voici un squelette très simple d’une 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. Une fois la passe de mesure passée, la taille souhaitée peut indiquer que la taille naturelle, si la taille disponible que vous avez passée pour la mesure était plus petite. Si la taille naturelle est supérieure à la taille disponible que vous avez passée pour Measure, la taille souhaitée est limitée à availableSize. C’est ainsi que l’implémentation interne de Measure se comporte, et vos remplacements de disposition doivent prendre en compte ce comportement.

Certains éléments n’ont pas de taille naturelle, car ils ont des valeurs automatiques pour Height et Width. Ces éléments utilisent la valeur availableSize complète, car c’est ce qu’une valeur automatique représente : dimensionner l’élément à la taille maximale disponible, que le parent de disposition immédiate communique en appelant Measure avec availableSize. Dans la pratique, il existe toujours une mesure à laquelle une interface utilisateur est dimensionnée (même si c’est la fenêtre de niveau supérieur.) Finalement, la passe de mesure résout toutes les valeurs automatiques en contraintes parentes et tous les éléments de valeur automatique obtiennent des mesures réelles (que vous pouvez obtenir en vérifiant ActualWidth et ActualHeight, une fois la disposition terminée).

Il est légal de passer une taille à Measure qui a au moins une dimension infinie, pour indiquer que le panneau peut tenter de se dimensionner lui-même pour ajuster les mesures de son contenu. Chaque élément enfant mesuré définit sa valeur DesiredSize à l’aide de sa taille naturelle. Ensuite, pendant la passe d’organisation, le panneau s’organise généralement à l’aide de cette taille.

Les éléments de texte tels que TextBlock ont un ActualWidth calculé et ActualHeight en fonction de leur chaîne de texte et de leurs 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 votre logique de panneau. Le texte de découpage est une expérience d’interface utilisateur particulièrement incorrecte.

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

La valeur de retour MeasureOverride est basée sur la logique du panneau qui interprète la valeur DesiredSize ou d’autres considérations de taille pour chacun des éléments enfants dans Children lorsque Measure est appelé sur eux. Que faire avec les valeurs DesiredSize des enfants et comment la valeur de retour MeasureOverride doit les utiliser est jusqu’à l’interprétation de votre propre logique. Vous n’ajoutez généralement pas 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 peut être rogné. Vous comparez généralement la taille totale des enfants à la taille disponible du panneau et apportez des ajustements si nécessaire.

Conseils et conseils

  • Dans l’idéal, un panneau personnalisé doit être le premier visuel vrai dans une composition d’interface utilisateur, peut-être à un niveau immédiatement sous Page, UserControl ou un autre élément qui est la racine de la page XAML. Dans les implémentations MeasureOverride, ne retournez pas régulièrement la taille d’entrée sans examiner les valeurs. Si la taille de retour a une valeur Infini, cela peut lever des exceptions dans la logique de disposition du runtime. Une valeur Infini peut provenir de la fenêtre principale de l’application, qui est défilante et n’a donc pas de hauteur maximale. D’autres contenus défilants peuvent avoir le même comportement.
  • Une autre erreur courante dans les implémentations MeasureOverride consiste à retourner une nouvelle taille par défaut (les valeurs de hauteur et de largeur sont 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 rendu. Toutefois, une taille par défaut entraîne la taille de votre panneau qui n’est pas correctement dimensionnée par son hôte. Il ne demande pas d’espace dans l’interface utilisateur et n’obtient donc aucun espace et ne s’affiche pas. Dans le cas contraire, tout le code de votre panneau peut fonctionner correctement, mais vous ne verrez toujours pas votre panneau ou son contenu s’il est composé avec une hauteur nulle, une largeur nulle.
  • Dans les remplacements, évitez la tentation de convertir des éléments enfants en FrameworkElement et d’utiliser des propriétés calculées à la suite de la disposition, en particulier ActualWidth et ActualHeight. Pour les scénarios les plus courants, vous pouvez baser la logique sur la valeur DesiredSize de l’enfant et vous n’aurez pas besoin des propriétés associées à Height ou Width d’un élément enfant. Dans les cas spécialisés, où vous connaissez le type d’élément et que vous disposez d’informations supplémentaires, par exemple la taille naturelle d’un fichier image, vous pouvez utiliser les informations spécialisées de votre élément, car il ne s’agit pas d’une valeur qui est activement modifiée par les systèmes de disposition. L’inclusion de propriétés calculées par la disposition dans le cadre de la logique de disposition augmente considérablement le risque de définir une boucle de disposition involontaire. Ces boucles entraînent une condition dans laquelle une disposition valide ne peut pas être créée et le système peut lever une disposition LayoutCycleException si la boucle n’est pas récupérable.
  • Les panneaux divisent généralement leur espace disponible entre plusieurs éléments enfants, bien que exactement la façon dont l’espace est divisé varie. Par exemple, Grid implémente la logique de disposition qui utilise ses valeurs RowDefinition et ColumnDefinition pour diviser l’espace en cellules Grid, prenant en charge le dimensionnement en étoile et les valeurs de pixels. S’il s’agit de valeurs de pixels, la taille disponible pour chaque enfant est déjà connue, c’est-à-dire ce qui est passé comme taille d’entrée pour une mesure de style grille.
  • Les panneaux eux-mêmes peuvent introduire un espace réservé pour le remplissage entre les éléments. Si vous effectuez cette opération, veillez à exposer les mesures en tant que propriété distincte de Margin ou toute propriété Padding .
  • Les éléments peuvent avoir des valeurs pour leurs propriétés ActualWidth et ActualHeight en fonction d’un passage de disposition précédent. Si les valeurs changent, le code de l’interface utilisateur de l’application peut placer des gestionnaires pour LayoutUpdated sur des éléments s’il existe une logique spéciale à exécuter, mais la logique du panneau n’a généralement pas besoin de vérifier les modifications avec la gestion des événements. Le système de disposition détermine déjà quand réexécuter la disposition parce qu’une propriété pertinente pour la disposition a changé de valeur et que measureOverride ou ArrangeOverride d’un panneau sont appelées automatiquement dans les circonstances appropriées.

ArrangeOverride

La méthode ArrangeOverride a une valeur de retour Size utilisée par le système de disposition lors du rendu du panneau lui-même, lorsque la méthode Arrange est appelée sur le panneau par son parent dans la disposition. Il est courant que l’entrée finalSize et la taille retournée par ArrangeOverride soient identiques. Si ce n’est pas le cas, cela signifie que le panneau tente de se faire une taille différente de celle des autres participants à la revendication de disposition. La taille finale était basée sur l’exécution précédente de la passe de mesure de disposition par le biais de votre code de panneau. C’est pourquoi le retour d’une autre taille n’est pas classique : cela signifie que vous ignorez délibérément la logique de mesure.

Ne retournez pas une taille avec un composant Infinity . La tentative d’utilisation d’une telle taille lève une exception de la disposition interne.

Toutes les implémentations ArrangeOverride doivent effectuer une boucle dans Children 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 comme résultat (toutefois, l’élément en question déclenche généralement un événement LayoutUpdated).

Voici un squelette très basique d’une 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 se produire sans être précédée d’une passe de mesure. Toutefois, cela se produit uniquement lorsque le système de disposition n’a déterminé qu’aucune propriété n’a changé qui aurait affecté les mesures précédentes. Par exemple, si un alignement change, il n’est pas nécessaire de mesurer à nouveau cet élément particulier, car son desiredSize ne change pas lorsque son choix d’alignement change. En revanche, si ActualHeight change sur un élément d’une disposition, une nouvelle passe de mesure est nécessaire. Le système de disposition détecte automatiquement les modifications de mesures vraies et appelle à nouveau la passe de mesure, puis exécute une autre passe d’organisation.

L’entrée de Arrange prend une valeur Rect. La façon la plus courante de construire ce Rect consiste à utiliser le constructeur qui a une entrée point et une entrée Size. Le point est le point où le coin supérieur gauche du cadre englobant de l’élément doit être placé. La taille est les dimensions utilisées pour afficher cet élément particulier. Vous utilisez souvent le DesiredSize pour cet élément comme valeur Size, car l’établissement de LairedSize pour tous les éléments impliqués dans la disposition était l’objectif de la passe de mesure de disposition. (Le passage de mesure détermine le dimensionnement de tous les éléments de manière itérative afin que le système de disposition puisse optimiser la façon dont les éléments sont placés une fois qu’ils sont placés à la passe d’organisation.)

Ce qui varie généralement entre les implémentations ArrangeOverride est la logique selon laquelle le panneau détermine le composant Point de la façon dont il organise chaque enfant. Un panneau de positionnement absolu tel que Canvas utilise les informations de positionnement explicites qu’il obtient de chaque élément via Canvas.Left et Canvas.Top valeurs. Un panneau de division d’espace tel que Grid aurait des opérations mathématiques qui divisent l’espace disponible en cellules et chaque cellule aurait une valeur x-y pour laquelle son contenu doit être placé et organisé. Un panneau adaptatif tel que StackPanel peut s’étendre pour s’adapter au contenu dans sa dimension d’orientation.

Il existe encore des influences de positionnement supplémentaires sur les éléments de disposition, au-delà de ce que vous contrôlez directement et passez à Arrange. Celles-ci proviennent de l’implémentation native interne de Arrange commune à tous les types dérivés de FrameworkElement et augmentées par d’autres types tels que des éléments de texte. Par exemple, les éléments peuvent avoir une marge et un alignement, et certains peuvent avoir un remplissage. Ces propriétés interagissent souvent. Pour plus d’informations, consultez Alignement, marge et remplissage.

Panneaux et contrôles

Évitez de placer des fonctionnalités dans un panneau personnalisé qui doit être généré en tant que contrôle personnalisé. Le rôle d’un panneau consiste à présenter tout contenu d’élément enfant qui existe dans celui-ci, en tant que fonction de disposition qui se produit automatiquement. Le panneau peut ajouter des décorations au contenu (similaire à la façon dont une bordure ajoute la bordure autour de l’élément qu’il présente) ou effectuer d’autres ajustements liés à la disposition comme le remplissage. Mais c’est à peu près aussi loin que vous devez aller lors de l’extension de la sortie de l’arborescence visuelle au-delà de la création de rapports et l’utilisation d’informations des enfants.

S’il existe une interaction 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 au contenu qu’il présente, même si l’objectif est d’empêcher la capture, car les barres de défilement, les pouces et ainsi de suite sont des parties de contrôle interactives. (Le contenu peut avoir des barres de défilement après tout, mais vous devez laisser cela jusqu’à 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 également é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.

Une raison pour laquelle la distinction entre le panneau de configuration et le panneau est importante est due à Microsoft UI Automation et à l’accessibilité. Les panneaux fournissent un comportement de disposition visuelle, et non un comportement logique. La façon dont un élément d’interface utilisateur apparaît visuellement n’est pas un aspect de l’interface utilisateur qui est généralement important pour les scénarios d’accessibilité. L’accessibilité consiste à exposer les parties d’une application qui sont logiquement importantes pour comprendre une interface utilisateur. Lorsque l’interaction est nécessaire, les contrôles doivent exposer les possibilités d’interaction à l’infrastructure UI Automation. Pour plus d’informations, consultez Homologues Automation personnalisés.

Autre API de disposition

Il existe d’autres API qui font partie du système de disposition, mais qui ne sont pas déclarées par le panneau. 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 une passe de mesure, mais les deux autres le font. N’appelez jamais ces méthodes à partir d’une substitution de méthode de disposition, car elles sont presque sûrs de provoquer 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 en détectant les modifications apportées aux propriétés de disposition définies par l’infrastructure, telles que Width , etc.
  • LayoutUpdated est un événement déclenché lorsqu'un aspect de disposition de l'élément a changé. Ce n’est pas spécifique aux panneaux ; l’événement est défini par FrameworkElement.
  • SizeChanged qui ne se déclenche qu'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. Il existe des cas où LayoutUpdated se déclenche, mais SizeChanged ne le fait pas. Par exemple, le contenu interne peut être réorganisé, mais la taille de l’élément n’a pas changé.

Référence

Concepts