我只是希望左边有流动文本,右边有一个帮助框。

帮助框应该一直延伸到底部。

如果你拿出下面的外部StackPanel,它工作得很好。

但由于布局的原因(我动态插入UserControls),我需要有包装StackPanel。

我如何让GroupBox扩展到StackPanel的底部,正如你所看到的,我已经尝试过了:

VerticalAlignment =“伸展” VerticalContentAlignment =“伸展” 高地=“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而不是StackPanel清除它。总的来说,我发现自己现在越来越多地使用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>

当前回答

发生这种情况的原因是因为堆栈面板测量的每个子元素都是正无穷大,作为堆叠元素的轴的约束。子控件必须返回它们想要的大小(正无穷大在任何一个轴上都不是MeasureOverride的有效返回值),因此它们返回所有内容都合适的最小大小。他们不知道自己到底要填多少空间。

If your view doesn’t need to have a scrolling feature and the answer above doesn't suit your needs, I would suggest implement your own panel. You can probably derive straight from StackPanel and then all you will need to do is change the ArrangeOverride method so that it divides the remaining space up between its child elements (giving them each the same amount of extra space). Elements should render fine if they are given more space than they wanted, but if you give them less you will start to see glitches.

If you want to be able to scroll the whole thing then I am afraid things will be quite a bit more difficult, because the ScrollViewer gives you an infinite amount of space to work with which will put you in the same position as the child elements were originally. In this situation you might want to create a new property on your new panel which lets you specify the viewport size, you should be able to bind this to the ScrollViewer’s size. Ideally you would implement IScrollInfo, but that starts to get complicated if you are going to implement all of it properly.

其他回答

发生这种情况的原因是因为堆栈面板测量的每个子元素都是正无穷大,作为堆叠元素的轴的约束。子控件必须返回它们想要的大小(正无穷大在任何一个轴上都不是MeasureOverride的有效返回值),因此它们返回所有内容都合适的最小大小。他们不知道自己到底要填多少空间。

If your view doesn’t need to have a scrolling feature and the answer above doesn't suit your needs, I would suggest implement your own panel. You can probably derive straight from StackPanel and then all you will need to do is change the ArrangeOverride method so that it divides the remaining space up between its child elements (giving them each the same amount of extra space). Elements should render fine if they are given more space than they wanted, but if you give them less you will start to see glitches.

If you want to be able to scroll the whole thing then I am afraid things will be quite a bit more difficult, because the ScrollViewer gives you an infinite amount of space to work with which will put you in the same position as the child elements were originally. In this situation you might want to create a new property on your new panel which lets you specify the viewport size, you should be able to bind this to the ScrollViewer’s size. Ideally you would implement IScrollInfo, but that starts to get complicated if you are going to implement all of it properly.

另一种方法是使用包含一列和n行的Grid。将所有行高设置为Auto,最底端的行高设置为1*。

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

你可以用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

我建议你看看SpicyTaco.AutoGrid。这是非常有用的表单在WPF代替DockPanel, StackPanel和Grid和解决问题与拉伸非常容易和优雅。看看GitHub上的readme就知道了。

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

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

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

听起来好像你想要一个StackPanel,其中最后一个元素使用了所有剩余的空间。但是为什么不用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>