web-dev-qa-db-fra.com

Comment utiliser DockStyle.Fill pour les contrôles standard dans WPF?

Je suis habitué aux formulaires Windows, je crée un panneau, y place des contrôles et leur donne DockStyle.Fill pour maximiser leur taille par rapport au panneau environnant.

Dans WPF, je veux avoir la même chose. J'ai un TabControl et je veux que sa taille remplisse autant que possible le formulaire. J'ai un contrôle de ruban (RibbonControlsLibrary) et veux que le reste du formulaire soit rempli avec TabControl à la taille maximale.

(Je ne veux pas ancrer des contrôles tels que l'ancrage dans Visual Studio, mais uniquement les anciens mécanismes d'ancrage)

87
citronas

L'équivalent WPF de DockStyle.Fill de WinForms est:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Ceci est la valeur par défaut pour presque les contrôles, donc en général, vous n'avez rien à faire pour qu'un contrôle WPF remplisse son conteneur parent: ils le font automatiquement. Cela est vrai pour tous les conteneurs qui ne réduisent pas leurs enfants à la taille minimale.

erreurs courantes

Je vais maintenant expliquer plusieurs erreurs courantes qui empêchent HorizontalAlignment="Stretch" VerticalAlignment="Stretch" de travailler comme prévu.

1. Hauteur ou largeur explicite

Une erreur courante consiste à spécifier explicitement une largeur ou une hauteur pour un contrôle. Donc si vous avez ceci:

<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>

Supprimez simplement les attributs largeur et hauteur:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>

2. Le panneau contenant contraint le contrôle à une taille minimale

Une autre erreur courante est d’avoir le panneau contenant votre contrôle aussi serré que possible. Par exemple, un StackPanel vertical pressera toujours son contenu verticalement aussi petit que possible:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>

Passez à un autre panneau et vous serez prêt à partir:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>

De même, toute ligne ou colonne de la grille dont la hauteur est "Auto" réduira de la même manière son contenu dans cette direction.

Voici quelques exemples de conteneurs qui ne pressent pas leurs enfants:

  • ContentControls ne serre jamais leurs enfants (cela inclut Border, Button, CheckBox, ScrollViewer et bien d’autres)
  • Grille avec une seule ligne et colonne
  • Grille avec "*" tailles de lignes et de colonnes
  • DockPanel ne serre pas son dernier enfant
  • TabControl ne serre pas son contenu

Voici quelques exemples de conteneurs qui pressent leurs enfants:

  • StackPanel se resserre dans le sens de l'orientation
  • La grille avec une rangée ou une colonne de taille "Auto" se serre dans cette direction
  • DockPanel presse tout sauf son dernier enfant dans la direction de son quai
  • TabControl compresse son en-tête (ce qui est affiché sur l'onglet)

. Hauteur ou largeur explicite plus loin

C'est incroyable de voir combien de fois je vois Grid ou DockPanel avec une hauteur et une largeur explicites, comme ceci:

<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

En général, vous ne voulez jamais attribuer à un panneau une hauteur ou une largeur explicite. Ma première étape de diagnostic des problèmes de mise en page consiste à supprimer chaque hauteur ou largeur explicite que je peux trouver.

4. La fenêtre est SizeToContent alors qu'elle ne devrait pas l'être

Lorsque vous utilisez SizeToContent, votre contenu sera réduit à la taille minimale. Dans de nombreuses applications, cela est très utile et constitue le bon choix. Mais si votre contenu n'a pas de taille "naturelle", vous voudrez probablement omettre SizeToContent.

175
Ray Burns

Vous pouvez faire ce que vous voulez en disant simplement DockPanelLastChildFill="True" et ensuite, assurez-vous que ce que vous voulez être le remplisseur est bien le dernier enfant!

La grille est la bête d'une disposition que vous pouvez utiliser, mais DockPanel est généralement le bon choix pour votre panneau de présentation le plus à l'extérieur. Voici un exemple de pseudocode:

<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>
7
Berryl

enveloppez simplement vos contrôles dans une grille de deux lignes. La grille utilisera automatiquement tout l’espace qui lui est attribué et vous pouvez définir les lignes pour occuper tout l’espace restant en leur attribuant une hauteur de "*". La première ligne de mon exemple (Height = "Auto") occupera tout l'espace nécessaire au ruban. J'espère que ça t'as aidé.

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>

En ajoutant l'attribut "Grid.Row = .." aux contrôles enfants de la grille, ils sont affectés aux lignes de la grille. Ensuite, la grille redimensionnera ses enfants comme défini par les définitions de ligne.

5
andyp

J'essayais beaucoup de méthodes ici mais je ne peux pas résoudre mon problème. (Remplissez autre contrôle dans le contrôle)

Jusqu'à ce que j'ai trouvé it

<Name_Control Height="auto" Width="auto"/>
//default
//HorizontalAlignment="Stretch" 
//VerticalAlignment="Stretch"

Exemple:

//UserControl:
<UserControl Name="UC_Test" Height="auto" Width="auto" />
//Grid: 
<Grid Name="Grid_test" Grid.ColumnSpan="2" Grid.Row="2" />
//Code: 
Grid_test.Children.Add(UC_Test);

Pour la conception facile

<UserControl Name="UC_Test" Height="100" Width="100" />
//Code
Grid_test.Children.Add(UC_Test);
UC_Test.Width = Double.NaN;
UC_Test.Height = Double.NaN;
0