2009-02-06 9 views
5

J'ai écrit un contrôle utilisateur WPF et une partie de celui-ci implique l'ajout dynamique d'éléments à un canevas qui affecte la hauteur de ce canevas. Le canevas est imbriqué dans une grille. Lorsque j'ajoute dynamiquement mes éléments, la hauteur du canevas change, mais le canevas finit par s'étendre au-delà du bord du contrôle global plutôt que de redimensionner le contrôle et de devenir plus grand. Comment puis-je forcer le contrôle à redimensionner correctement? J'ai l'impression que j'ai besoin d'appeler ou de contourner Mesurer ou Réorganiser mais je n'ai aucune chance avec l'une ou l'autre méthode - probablement parce que je les appelle avec des paramètres incorrects ou parce qu'elles ne sont pas les bonnes méthodes.Force un contrôle WPF personnalisé pour redimensionner correctement

+0

Utilisez-vous le mélange? –

+0

Je suis arrivé à cette question parce que je suis aussi * dynamiquement * en ajoutant des éléments à un contrôle et il n'est pas en train de redimensionner même si j'ai remplacé MeasureOverride (qui fonctionne). Le problème est de forcer un réarrangement des éléments de l'interface utilisateur affectés à chaque nouvel élément ajouté afin qu'ils se déplacent pour s'adapter à la croissance. –

+0

J'ai résolu mon problème, et il semble que l'événement ItemsChanged invalide effectivement la mise en page et force une mise à jour. Josh explique à juste titre que l'implémentation d'un MeasureOverride personnalisé fonctionnera. –

Répondre

1

Vous devez remplacer la méthode MeasureOverride de votre contrôle et renvoyer la taille souhaitée (la taille de votre canevas) à partir de là. Ensuite, le contrôle parent se redimensionner pour accueillir son enfant (s'il le peut).

16

Votre problème est que les panneaux Canvas ne sont pas redimensionnés pour s'adapter à leur contenu.

Vous avez fait référence à Mesurer et organiser. Connaissez-vous le système de mise en page à deux passes de WPF? Lisez cet article pour plus d'informations: WPF's Layout System.

Cet article décrit également ce que les différents panneaux font pour la mise en page. Chaque type de panneau est différent.

Dans WPF, les éléments reçoivent d'abord l'opportunité de déterminer leur taille. Les panels peuvent déterminer leur taille en fonction de la taille de leurs enfants, ou ils peuvent demander une taille fixe indépendamment de la taille de leurs enfants. Canvas est un exemple de ce dernier.

Les éléments sont ensuite dit quelle taille ils seront et demandé d'organiser eux-mêmes et leurs enfants.

Le type de panneau Grille autorise non seulement les lignes et les colonnes, mais il est également très efficace pour le dimensionnement automatique du contenu.

Le type StackPanel ne s'autosise pas du tout dans la dimension dans laquelle il est orienté, mais il s'auto-dimensionne dans l'autre dimension.

Le canevas peut être dimensionné automatiquement pour remplir un espace, mais il n'autorise jamais les enfants à la taille automatique. Il attire ses enfants aux coordonnées spécifiées et ne se soucie pas de leur taille.

Je suggère d'essayer une grille avec une seule rangée/colonne.

Ou vous pouvez créer une nouvelle classe Canvas qui a de meilleures capacités d'autosizing. Pendant la mesure, vous voudrez mesurer les éléments enfants et dimensionner votre toile en conséquence. Vous pourriez trouver une classe comme celle-ci utile sur la route.

Voici un article sur Auto Layout dans WPF. Si vous souhaitez créer un panneau personnalisé, voici un sous-sujet: Custom Panel Elements. Une autre chose: Vous pouvez également lier la largeur/hauteur de l'élément enfant aux propriétés ActualWidth et ActualHeight sur le canevas afin que l'enfant ajuste la taille de son parent. Vous pouvez utiliser un convertisseur pour définir un rapport de taille si nécessaire.

0

Vous pouvez utiliser UniFormGrid pour l'archiver.Définir les colonnes ou la ligne est égal à 1, de sorte que vous pouvez obtenir un des éléments disposés vertical/horizontal

<UniformGrid Columns="1"> 
    <Button Content="Content 1"/> 
    <Button Content="Content 2"/> 
    <Button Content="Content 3"/> 
</UniformGrid> 
2

Avez-vous essayé d'envelopper tout (le contenu de votre commande sur mesure) dans un Viewbox? par exemple

<UserControl> 
    <Border BorderBrush="Black" BorderThickness="1"> 
     <Viewbox> 
      <Grid> 
       <TextBlock Name="txtDefault" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16" Foreground="Black" Opacity="0.5" Text="Default" /> 
       <TextBlock Name="txtValue" FontSize="16" Foreground="Black" Visibility="Collapsed" /> 
       <TextBlock Name="txtKey" Grid.Column="1" FontSize="18" Foreground="Black" Visibility="Collapsed" /> 
      </Grid> 
     </Viewbox> 
    </Border> 
</UserControl> 
Questions connexes