2009-08-07 8 views
2

Je regardais FrameworkElement.MesureOverride sur MSDN, essayant de comprendre le mécanisme derrière le moteur de mise en page. Je suis tombé sur cette note intéressante:MesureOverride pour retourner plus que la taille disponible?

Au cours de ce processus, les éléments enfants peuvent renvoyer une taille DésiredSize plus grande que la taille availableSize initiale pour indiquer que l'élément enfant veut plus d'espace.

Ok. J'ai eu un réflecteur à proximité donc j'ai regardé MesureCore, qui s'appelle MesureOverride et j'ai remarqué que, d'après ce que j'ai pu comprendre, la valeur de retour de MesureOverride est toujours plafonnée entre 0 et la taille disponible. Alors qu'est-ce qui se passe avec ça?

Répondre

1

Un élément enfant peut demander plus d'espace. Que cela soit honoré par l'élément parent dépend de l'élément parent.

MeasureCore appelle uniquement MeasureOverride sur this. Vous n'obtenez qu'une très petite partie de l'histoire. The Layout System commence par appeler Measure sur le plus haut Panel dans l'arbre des éléments, qui appelle MeasureCore sur this. Cependant, MeasureCore dans FrameworkElement appelle MeasureOverride dans un couple d'endroits. Où est-ce que vous le voyez entre 0 et availableSize?

Edit: Re: « bien, la dernière ligne de MeasureCore ... »

Comme je l'ai dit, vous êtes à la recherche à une petite partie de tout ce qui se passe.

  1. Tous les contrôles ont 1 manière très courante de demander plus d'espace que nécessaire: Margin. Vous devez écrire un contrôle personnalisé pour demander encore plus d'espace que cela.
  2. Les contraintes que vous voyez dans MeasureCore, de ce que je peux dire, ont à voir avec les limites MinWidth/MinHeight et MaxWidth/MaxHeight, si elles sont définies.

Alors oui, un contrôle - comme le dit la documentation - peut demander plus d'espace que nécessaire. Aucun des contrôles par défaut semble faire cela en dehors de leurs Margin s, et les conteneurs tels que les panneaux n'ont pas à le respecter. La plupart des circonstances ne tirent pas parti de ce que vous lisez dans la documentation, car dans la plupart des cas, cela n'aurait aucun sens, que ce soit du point de vue du parent de l'enfant.

Si vous avez créé un UserControl, est débarrassé des Width et Height valeurs dans le XAML et passer outre MeasureOverride retourner un Size arbitraire, puis placez une instance de celui-ci dans un Canvas, vous verriez afficher au Size vous êtes revenu .

Cette fonctionnalité du système de mise en page peut être utile si vous créez des panneaux personnalisés et des contrôles personnalisés ou des contrôles utilisateur, mais que ce n'est probablement pas le cas. Mais c'est là. La documentation est correcte.

+0

bien, la dernière ligne de MesureCore est return new Size (Math.Max ​​(0.0, width), Math.Max ​​(0.0, height)); (c'est la seule déclaration de retour) et un peu avant, il y a quelques ifs comme if (width> availableSize.Width) width = availableSize.Width; – subb

0

Si vous retournez un Size>availableSize à partir de votre propre méthode MeasureOverride, FrameworkElement.MeasureCore (appeler votre méthode) se souviendra, mais DesiredSize sera mis = availableSize. Cela garantit que le contrôle enfant sera adapté à (par exemple) la cellule de grille avec Largeur/Hauteur explicitement spécifiée. MAIS parce que FrameworkElement.MeasureCore se souvient de votre "non clippé" DesiredSize, dans ArrangeOverride vous devriez recevoir un paramètre = votre original DesiredSize. À la suite de cela votre contrôle "virtuellement" organise les enfants selon son DesiredSize original, mais l'implémentation FrameworkElement écrira votre contrôle pour une telle cellule Grid parent. La manière concrète d'écrêtage dépendra des valeurs réelles des propriétés comme Horizontal/VerticalAlignment (propriétés de votre contrôle).