it-swarm.com.de

Wie kann man StackPanels Kinder dazu bringen, den maximalen Platz nach unten zu füllen?

Ich möchte einfach links fließenden Text und rechts eine Hilfebox.

Das Hilfefenster sollte ganz nach unten zeigen.

Wenn Sie das äußere StackPanel unten herausnehmen, funktioniert es hervorragend.

Aber aus Gründen des Layouts (ich füge UserControls dynamisch ein) muss ich das umhüllende StackPanel haben.

Wie Sie sehen, kann ich die GroupBox bis zum unteren Rand des StackPanels ausdehnen. Ich habe Folgendes versucht:

  • VerticalAlignment = "Stretch"
  • VerticalContentAlignment = "Strecken"
  • Höhe = "Auto"

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>

Antworten:

Vielen Dank, dass Sie DockPanel anstelle von StackPanel verwendet haben. Im Allgemeinen verwende ich DockPanel immer häufiger für das WPF-Layout. Hier ist die feste 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" 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>
332
Edward Tanguay

Es hört sich so an, als wollten Sie ein StackPanel, bei dem das letzte Element den gesamten verbleibenden Speicherplatz belegt. Aber warum nicht ein DockPanel verwenden? Dekoriere die anderen Elemente in DockPanel mit DockPanel.Dock="Top", und dann kann Ihr Hilfesteuerelement den verbleibenden Speicherplatz ausfüllen.

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>

Wenn Sie sich auf einer Plattform ohne DockPanel befinden (z. B. WindowsStore), können Sie den gleichen Effekt mit einem Raster erzielen. Im folgenden Beispiel werden stattdessen Raster verwendet:

<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>
317
Mark Heath

Der Grund dafür ist, dass das Stapelbedienfeld jedes untergeordnete Element mit einer positiven Unendlichkeit als Einschränkung für die Achse misst, entlang der es Elemente stapelt. Die untergeordneten Steuerelemente müssen zurückgeben, wie groß sie sein möchten (positive Unendlichkeit ist keine gültige Rückgabe von MeasureOverride in beiden Achsen), damit sie die kleinste Größe zurückgeben, in die alles passt. Sie können nicht wissen, wie viel Platz sie wirklich füllen müssen.

Wenn für Ihre Ansicht keine Bildlauffunktion erforderlich ist und die obige Antwort nicht Ihren Anforderungen entspricht, würde ich vorschlagen, Ihr eigenes Panel zu implementieren. Sie können wahrscheinlich direkt von StackPanel ableiten, und dann müssen Sie nur die ArrangeOverride -Methode ändern, damit der verbleibende Speicherplatz zwischen den untergeordneten Elementen aufgeteilt wird (und diese jeweils den gleichen zusätzlichen Speicherplatz erhalten). . Elemente sollten gut gerendert werden, wenn sie mehr Platz haben, als sie wollten. Wenn Sie ihnen weniger Platz geben, sehen Sie jedoch Störungen.

Wenn Sie in der Lage sein möchten, das Ganze zu scrollen, werden die Dinge leider etwas schwieriger, da der ScrollViewer Ihnen unendlich viel Platz zum Arbeiten bietet, wodurch Sie an die gleiche Position gebracht werden, an der sich die untergeordneten Elemente befanden ursprünglich. In diesem Fall möchten Sie möglicherweise in Ihrem neuen Bedienfeld eine neue Eigenschaft erstellen, mit der Sie die Größe des Ansichtsfensters festlegen können. Sie sollten diese an die Größe des ScrollViewer binden können. Idealerweise würden Sie IScrollInfo implementieren, aber das wird kompliziert, wenn Sie alles richtig implementieren.

102
Caleb Vear

Eine alternative Methode ist die Verwendung eines Rasters mit einer Spalte und n Zeilen. Setzen Sie alle Zeilenhöhen auf Auto und die unterste Zeilenhöhe auf 1*.

Ich bevorzuge diese Methode, weil ich festgestellt habe, dass Grids eine bessere Layout-Leistung haben als DockPanels, StackPanels und WrapPanels. Aber es sei denn, Sie verwenden sie in einer ItemTemplate (in der das Layout für eine große Anzahl von Elementen ausgeführt wird), werden Sie es wahrscheinlich nie bemerken.

56
rcabr

Sie können geänderte Version von StackPanel verwenden:

<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>

Der erste Knopf wird gefüllt.

Sie können es über Nuget installieren:

Install-Package SpicyTaco.AutoGrid

Ich empfehle auch einen Blick auf wpf-autogrid . Es ist sehr nützlich für Formulare in WPF anstelle von DockPanel, StackPanel und Grid und löst Probleme beim Dehnen sehr einfach und elegant. Schauen Sie sich die Readme-Datei auf Github an.

<st:AutoGrid Columns="160,*" ChildMargin="3">
    <Label Content="Name:"/>
    <TextBox/>

    <Label Content="E-Mail:"/>
    <TextBox/>

    <Label Content="Comment:"/>
    <TextBox/>
</st:AutoGrid>
14
Dvor_nik