代码之家  ›  专栏  ›  技术社区  ›  Edward Tanguay

如何让StackPanel的孩子们向下填充最大的空间?

  •  406
  • Edward Tanguay  · 技术社区  · 16 年前

    StackPanel

    但由于布局的原因(我动态插入UserControls),我需要进行包装 堆栈面板 .

    我如何获得 GroupBox 向下延伸到底部 堆栈面板 如您所见,我已经尝试过:

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

    答案:

    谢谢马克,使用 DockPanel 堆栈面板 把它清理干净。总的来说,我发现自己在使用 DockPanel 现在WPF布局越来越多,以下是固定的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>
    
    4 回复  |  直到 5 年前
        1
  •  371
  •   Mark Heath    10 年前

    听起来你想要一个 StackPanel 其中最后一个元素耗尽了所有剩余空间。但是为什么不使用a DockPanel DockPanel 随着 DockPanel.Dock="Top" ,然后您的帮助控件可以填充剩余的空间。

    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>
    

    DockPanel 可用(例如WindowsStore),您可以使用网格创建相同的效果。以下是使用网格完成的上述示例:

    <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>
    
        2
  •  113
  •   Caleb Vear    16 年前

    之所以会发生这种情况,是因为堆栈面板以正无穷大作为堆栈元素所沿轴的约束来测量每个子元素。子控件必须返回它们想要的大小(正无穷大不是有效的返回值 MeasureOverride

    如果你的视图不需要滚动功能,而上面的答案不符合你的需求,我建议你实现自己的面板。您可能可以直接从StackPanel中导出,然后只需更改 ArrangeOverride 方法,以便在其子元素之间划分剩余空间(为每个子元素提供相同数量的额外空间)。如果元素被给予比它们想要的更多的空间,它们应该会渲染得很好,但如果你给它们更少的空间,你就会开始看到小故障。

    IScrollInfo ,但如果你要正确地实现所有这些,情况就会变得复杂。

        3
  •  70
  •   rcabr    16 年前

    另一种方法是使用具有一列的网格 n Auto ,最底部的行高度为 1* .

    我更喜欢这种方法,因为我发现网格的布局性能比DockPanels、StackPanels和WrapPanels更好。但是,除非您在ItemTemplate中使用它们(其中对大量项目执行布局),否则您可能永远不会注意到。

        4
  •  23
  •   Eliahu Aaron Guru Stron    5 年前

    您可以使用 SpicyTaco.AutoGrid -的修改版本 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>
    

    第一个按钮将被填充。

    您可以通过NuGet安装它:

    Install-Package SpicyTaco.AutoGrid
    

    我建议你看看 辣土豆。自动网格 。它对WPF中的表单非常有用,而不是 DockPanel , 堆栈面板 Grid 轻松优雅地解决伸展问题。请查看GitHub上的自述文件。

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