Je veux simplement un texte fluide à gauche et une boîte d’aide à droite.
La boîte d’aide devrait s’étendre jusqu’en bas.
Si vous retirez le StackPanel externe ci-dessous, cela fonctionne très bien.
Mais pour des raisons de mise en page (j'insère UserControls de manière dynamique), je dois disposer du wrapper StackPanel.
Comment puis-je faire en sorte que la GroupBox s'étende jusqu'au bas du StackPanel, comme vous pouvez le constater, j'ai déjà essayé:
XAML:
<Window x:Class="TestDynamic033.Test3"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Title="Test3" Height="300" Width="600">
<StackPanel
VerticalAlignment="Stretch"
Height="Auto">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Margin="10">
<GroupBox
DockPanel.Dock="Right"
Header="Help"
Width="100"
Background="Beige"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" />
</GroupBox>
<StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
<TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
</StackPanel>
</DockPanel>
</StackPanel>
</Window>
Merci Mark, l’utilisation de DockPanel au lieu de StackPanel a permis de résoudre le problème. En général, je me retrouve de plus en plus à utiliser DockPanel pour la mise en page WPF, voici le XAML corrigé:
<Window x:Class="TestDynamic033.Test3"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
Title="Test3" Height="300" Width="600" MinWidth="500" MinHeight="200">
<DockPanel
VerticalAlignment="Stretch"
Height="Auto">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
MinWidth="400"
Margin="10">
<GroupBox
DockPanel.Dock="Right"
Header="Help"
Width="100"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<Border CornerRadius="3" Background="Beige">
<TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap"
Padding="5"/>
</Border>
</GroupBox>
<StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
<TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
</StackPanel>
</DockPanel>
</DockPanel>
</Window>
On dirait que vous voulez un StackPanel
où l’élément final utilise tout l’espace restant. Mais pourquoi ne pas utiliser un DockPanel
? Décorez les autres éléments de la DockPanel
avec DockPanel.Dock="Top"
, puis le contrôle de votre aide pourra remplir l'espace restant.
XAML:
<DockPanel Width="200" Height="200" Background="PowderBlue">
<TextBlock DockPanel.Dock="Top">Something</TextBlock>
<TextBlock DockPanel.Dock="Top">Something else</TextBlock>
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Margin="10">
<GroupBox
DockPanel.Dock="Right"
Header="Help"
Width="100"
Background="Beige"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<TextBlock Text="This is the help that is available on the news screen."
TextWrapping="Wrap" />
</GroupBox>
<StackPanel DockPanel.Dock="Left" Margin="10"
Width="Auto" HorizontalAlignment="Stretch">
<TextBlock Text="Here is the news that should wrap around."
TextWrapping="Wrap"/>
</StackPanel>
</DockPanel>
</DockPanel>
Si vous êtes sur une plate-forme pour laquelle DockPanel
n'est pas disponible (WindowsStore, par exemple), vous pouvez créer le même effet avec une grille. Voici l'exemple ci-dessus réalisé à l'aide de grilles à la place:
<Grid Width="200" Height="200" Background="PowderBlue">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock>Something</TextBlock>
<TextBlock>Something else</TextBlock>
</StackPanel>
<Grid Height="Auto" Grid.Row="1" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<GroupBox
Width="100"
Height="Auto"
Grid.Column="1"
Background="Beige"
Header="Help">
<TextBlock Text="This is the help that is available on the news screen."
TextWrapping="Wrap"/>
</GroupBox>
<StackPanel Width="Auto" Margin="10" DockPanel.Dock="Left">
<TextBlock Text="Here is the news that should wrap around."
TextWrapping="Wrap"/>
</StackPanel>
</Grid>
</Grid>
La raison en est que le panneau de pile mesure chaque élément enfant avec l'infini positif comme contrainte pour l'axe sur lequel il empile les éléments. Les contrôles enfants doivent renvoyer la taille souhaitée (l'infini positif n'est pas un retour valide de MeasureOverride dans l'un ou l'autre des axes) afin qu'ils renvoient la plus petite taille où tout ira bien. Ils n'ont aucun moyen de savoir combien d'espace ils doivent vraiment remplir.
Si votre vue n’a pas besoin de fonction de défilement et que la réponse ci-dessus ne correspond pas à vos besoins, je vous suggère d’implémenter votre propre panneau. Vous pouvez probablement dériver directement de StackPanel et tout ce que vous aurez à faire est de changer la méthode ArrangeOverride de sorte qu'elle divise l'espace restant entre ses éléments enfants (en leur donnant la même quantité d'espace supplémentaire) . Les éléments devraient rendre bien si on leur donne plus d'espace qu'ils ne le voulaient, mais si vous leur en donnez moins, vous commencerez à voir des problèmes.
Si vous voulez pouvoir faire défiler le texte entier, je crains que cela ne soit un peu plus difficile, car ScrollViewer vous laisse une infinité d'espace pour travailler, ce qui vous placera dans la même position que les éléments enfants. à l'origine. Dans ce cas, vous souhaiterez peut-être créer une nouvelle propriété sur votre nouveau panneau qui vous permettra de spécifier la taille de la fenêtre d'affichage. Vous devriez pouvoir la lier à la taille de ScrollViewer. Idéalement, vous devriez implémenter IScrollInfo , mais cela commence à se compliquer si vous voulez tout mettre en œuvre correctement.
Une autre méthode consiste à utiliser une grille avec une colonne et n lignes. Définissez toutes les hauteurs de ligne sur Auto
et la hauteur la plus basse sur 1*
.
Je préfère cette méthode car j'ai constaté que les grilles offrent de meilleures performances de disposition que DockPanels, StackPanels et WrapPanels. Mais à moins que vous ne les utilisiez dans un ItemTemplate (où la mise en page est effectuée pour un grand nombre d'éléments), vous ne le remarquerez probablement jamais.
Vous pouvez utiliser version modifiée de StackPanel:
<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10">
<Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/>
<Button Content="Cancel"/>
<Button Content="Save"/>
</st:StackPanel>
Le premier bouton sera rempli.
Vous pouvez l'installer via Nuget:
Install-Package SpicyTaco.AutoGrid
Je recommande également de jeter un oeil à wpf-autogrid . Il est très utile pour les formulaires dans WPF au lieu de DockPanel, StackPanel et Grid et résout le problème avec l’étirement très facilement et avec élégance. Il suffit de regarder le readme sur github.
<st:AutoGrid Columns="160,*" ChildMargin="3">
<Label Content="Name:"/>
<TextBox/>
<Label Content="E-Mail:"/>
<TextBox/>
<Label Content="Comment:"/>
<TextBox/>
</st:AutoGrid>