WPF的TextBox无法填充StackPanel

115

我有一个TextBox控件位于一个StackPanel中,该StackPanelOrientation属性被设置为Horizontal,但是我无法让TextBox填充剩余的StackPanel空间。

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="180" Width="324">

    <StackPanel Background="Orange" Orientation="Horizontal" >
        <TextBlock Text="a label" Margin="5" VerticalAlignment="Center"/>
        <TextBox Height="25" HorizontalAlignment="Stretch" Width="Auto"/>
    </StackPanel>
</Window>

这是它的样子:

alt text

为什么那个TextBox没有填满StackPanel?

我知道使用Grid控件可以更好地控制布局,但我对布局感到困惑。

6个回答

179

我也曾遇到过StackPanel的同样问题,这种行为是“按设计要求”的。 StackPanel旨在将事物“堆叠”起来,即使在可见区域之外,因此它不会允许您填充堆叠维度中的剩余空间。

您可以使用一个DockPanel,并将所有非填充控件停靠在Left上,并将LastChildFill设置为true,以模拟您想要的效果。

<DockPanel Background="Orange" LastChildFill="True">
    <TextBlock Text="a label" Margin="5" 
        DockPanel.Dock="Left" VerticalAlignment="Center"/>
    <TextBox Height="25" Width="Auto"/>
</DockPanel>

8
只是为了澄清 - LastChildFill 默认设置为“True”,并且将 TextBox 的 HorizontalAlignment 设置为 stretch 没有任何效果。 :-) - Goblin
1
@Goblin:是的...我复制并粘贴了原帖的代码,但忘记删除“HorizontalAlignment”了。 :) - Zach Johnson
1
@peter 很久没有做 WPF 相关的工作了,但你可以尝试使用某种网格布局,其中第一列设置为占用可用空间 (https://dev59.com/fWcs5IYBdhLWcg3w-Yv4)。 - Zach Johnson
6
我来晚了,但是@peter:你可以在DockPanel上使用FlowDirection="RightToLeft",这样你的最后一个子元素就会在左侧,占用剩余的空间。 - Dennis
使用Dockpanel解决这个问题有点奇怪。最好学习如何使用Grid控件。 - Bimo
显示剩余4条评论

27

我建议使用网格布局(Grid)代替:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="180" Width="324">

    <Grid Background="Orange">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Text="a label" 
           VerticalAlignment="Center"/>
        <TextBox  Grid.Column="1"/>
    </Grid>
</Window>

另一种解决这个问题的方法是在标签上方堆叠而不是在右侧。我注意到 UWP 有一个内置的标题属性可以用于此,不确定 WPF 是否存在标题属性。

<TextBox Header="MyLabel" />

9

实际话题的旧问题:

HorizontalAlignment="Stretch"

这是必需的。只要确保移除 width 即可。


为什么每个人都忽略了这个答案?对我很有用。 - Mikhail Kalashnikov
5
因为它在很多情况下都不起作用吗?我知道对我来说根本没用。这是我尝试的第一件事,我很惊讶它没有起作用:我得到了与原帖作者相同的行为。 - SolarBear

1

这件事情可能已经让我有几次很不愉快的经历。

我编写的代码使用了DockPanel,可能是因为这个原因。 但我不习惯使用它,并且它似乎无法满足我的需求。

我尝试使用水平StackPanel,但随后遇到了这个令人恼火的问题。

一个人可能会认为只需要设置或包装一些简单的东西。 然后发现它并不简单。 于是,一个人就会尝试各种方法并搜寻网络。

我不喜欢那些需要在代码中手动调整的棘手解决方案,我也曾遇到过。

所以,就像Bimo一样,我最终定义了一个额外的网格来放置只有两个控件。 这有点费力,但基本上清晰而简单。

    <!-- Used an extra grid to get both layout and tabbing right.-->
    <Grid Grid.Row="0" Margin="5,5,5,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <TextBox Grid.Column="0" Name="UriTextBox" Text="{Binding Uri}"/>
        <Button Grid.Column="1" Content="Go" Command="{Binding NavigateCommand}" IsDefault="True" Margin="5,0,0,0" Padding="20,0"/>
    </Grid>

0
此外,最终要注意样式,我花了一些时间才发现我的全局 TextBox 样式定义了一个高度,所以 TextBox 没有伸展。设置 Height="Auto" 后,TextBox 伸展了。 "实时属性浏览器" 是你的好朋友。 :)

0

我可以使用以下代码将一个文本框填充到 StackPanel 中:

<StackPanel Margin="5,5,5,5">
    <Label Content = "lblExample" Width = "70" Padding="0" HorizontalAlignment="Left"/>
    <TextBox Name = "txtExample" Text = "Example Text" HorizontalContentAlignment="Stretch"/>
</StackPanel>

水平填充StackPanel的文本框


2
是的,但不是在水平StackPanel中;你的是垂直的 :-) - JB.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,