410 Stimmen

Wie StackPanel's Kinder zu bekommen, um maximalen Platz nach unten zu füllen?

Ich möchte einfach fließenden Text auf der linken Seite und ein Hilfefeld auf der rechten Seite.

Das Hilfefeld sollte bis zum unteren Rand reichen.

Wenn Sie die äußere Hülle abnehmen StackPanel darunter funktioniert es hervorragend.

Aber aus Gründen des Layouts (ich füge UserControls dynamisch ein) muss ich die Umhüllung haben StackPanel .

Wie erhalte ich die GroupBox bis auf den Boden des StackPanel wie Sie sehen können, habe ich es versucht:

  • VerticalAlignment="Stretch"
  • VerticalContentAlignment="Stretch"
  • Height="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>

Antwort:

Danke Mark, mit DockPanel anstelle von StackPanel klärte es auf. Im Allgemeinen verwende ich DockPanel mehr und mehr jetzt für WPF-Layouting, 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>

0 Stimmen

Die Formatierung wurde korrigiert - sie mag es nicht, wenn man von einer Liste direkt zum Code übergeht.

1 Stimmen

Kann man eine GroupBox so dehnen, dass sie sich von selbst dehnt? Wenn ja, fügen Sie die übergeordneten Elemente eines nach dem anderen hinzu, bis Sie herausfinden, welches Element das Layout stört.

0 Stimmen

RoBorg: Gut zu wissen, das hat mich verblüfft, danke

395voto

Mark Heath Punkte 46572

Es klingt, als wollten Sie eine StackPanel wobei das letzte Element den gesamten verbleibenden Platz einnimmt. Aber warum nicht ein DockPanel ? Dekorieren Sie die anderen Elemente im DockPanel con DockPanel.Dock="Top" und dann kann Ihre Hilfssteuerung den verbleibenden Platz 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 verfügbar sind (z. B. WindowsStore), können Sie denselben Effekt mit einem Gitter erzielen. Hier ist das obige Beispiel, das stattdessen mit Gittern realisiert wurde:

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

116voto

Caleb Vear Punkte 2597

Der Grund dafür ist, dass das Stapel-Panel jedes untergeordnete Element mit positiver Unendlichkeit als Beschränkung für die Achse misst, entlang der es die Elemente stapelt. Die untergeordneten Steuerelemente müssen zurückgeben, wie groß sie sein sollen (positive Unendlichkeit ist keine gültige Rückgabe der MeasureOverride in beiden Achsen), so dass sie die kleinste Größe zurückgeben, in die alles passt. Sie haben keine Möglichkeit zu wissen, wie viel Platz sie wirklich ausfüllen müssen.

Wenn Ihre Ansicht nicht über eine Bildlauffunktion verfügen muss und die obige Antwort nicht Ihren Bedürfnissen entspricht, würde ich vorschlagen, ein eigenes Panel zu implementieren. Sie können wahrscheinlich direkt von StackPanel ableiten und alles was Sie dann tun müssen, ist die ArrangeOverride Methode, so dass der verbleibende Platz zwischen den untergeordneten Elementen aufgeteilt wird (wobei jedes Element den gleichen zusätzlichen Platz erhält). Die Elemente sollten gut gerendert werden, wenn sie mehr Platz erhalten, als sie wollten, aber wenn Sie ihnen weniger geben, werden Sie anfangen, Störungen zu sehen.

Wenn Sie in der Lage sein wollen, das ganze Ding zu scrollen, dann befürchte ich, dass die Dinge etwas schwieriger sein werden, weil der ScrollViewer Ihnen eine unendliche Menge an Platz zur Verfügung stellt, mit dem Sie arbeiten können, was Sie in die gleiche Position bringen wird, in der die Kindelemente ursprünglich waren. In dieser Situation solltest du eine neue Eigenschaft für dein neues Panel erstellen, mit der du die Größe des Ansichtsfensters festlegen kannst. Du solltest in der Lage sein, diese an die Größe des ScrollViewers zu binden. Idealerweise würden Sie implementieren IScrollInfo aber das wird langsam kompliziert, wenn man das alles richtig umsetzen will.

73voto

rcabr Punkte 1227

Eine alternative Methode ist die Verwendung eines Rasters mit einer Spalte und n Reihen. Setzen Sie alle Zeilenhöhen auf Auto und die Höhe der untersten Zeile auf 1* .

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

27voto

Dvor_nik Punkte 1011

Sie können verwenden SpicyTaco.AutoGrid - eine modifizierte Version von 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>

Die erste Taste wird gefüllt.

Sie können es über NuGet installieren:

Install-Package SpicyTaco.AutoGrid

Ich empfehle einen Blick auf SpicyTaco.AutoGrid . Es ist sehr nützlich für Formulare in WPF anstelle von DockPanel , StackPanel y Grid und lösen Sie das Problem mit der Dehnung sehr einfach und elegant. Schauen Sie einfach in die Readme auf GitHub.

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

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X