WPF:如何获得一个文本框来填充所有可用的水平 space?

WPF: How do I get a text box to fill all available horizontal space?

我正在 WPF 中创建一个表单。该窗体具有 TextBoxes,其左侧带有 TextBlocks。带有 GridLines 的屏幕截图如下:

我希望它看起来像这样(请原谅 MS Paint 风格):

问题是:文本框真的很小,除非我将 Horizo​​ntalAlignment 设置为 Stretch,但如果我这样做,我就无法将它们左对齐。如何让包含 TextBlock/TextBox 的网格向左对齐 使文本框填充全部可用 space?

如果我对宽度进行硬编码很容易,但这显然不适用于调整大小。我试过使用 Stack 和 Dock Panel 来控制网格,但没有成功。

我不能使用 HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time?,因为没有其他控件是我要填充的 space 的宽度。

我也无法使用 How to get controls in WPF to fill available space?,因为我的 xaml 中没有任何内容具有 Horizo​​ntalContentAllignment。我尝试在 ContentControls 中包装内容并使用 ItemsControl 来强制它,但没有成功。

表单的 xaml 如下。请注意,此 xaml 用于 'Create' header 下方和 3 个按钮右侧的控件。

<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <!--Left hand side content goes here-->
    <DockPanel Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"
                Margin="20,0,0,0">
        <Grid ShowGridLines="True" DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
                <ColumnDefinition SharedSizeGroup="TextBoxColumn"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0"
                       Text="Input Name:"
                       HorizontalAlignment="Right" VerticalAlignment="Center"/>
            <TextBox Grid.Column="1"
                     HorizontalAlignment="Stretch" VerticalAlignment="Center"
                     Style="{StaticResource FormTextBox}"
                     Margin="5,0,5,0"/>
        </Grid>
        <Grid ShowGridLines="True" DockPanel.Dock="Top" HorizontalAlignment="Left" VerticalAlignment="Top">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
                <ColumnDefinition SharedSizeGroup="TextBoxColumn"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0"
                       Text="Input Name:"
                       HorizontalAlignment="Right" VerticalAlignment="Center"/>
            <TextBox Grid.Column="1"
                     HorizontalAlignment="Stretch" VerticalAlignment="Center"
                     Style="{StaticResource FormTextBox}"
                     Margin="5,0,5,0"/>
        </Grid>
    </DockPanel>
</Grid>

FormTextBox 样式为:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBox"
       x:Key="FormTextBox">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Border CornerRadius="10"
                        Background="{StaticResource InputBrush}">
                    <Grid>
                        <Rectangle StrokeThickness="1"/>
                        <TextBox Margin="1"
                                 Text="{Binding RelativeSource={RelativeSource TemplatedParent},
                                                Path=Text,
                                                Mode=TwoWay,
                                                UpdateSourceTrigger=PropertyChanged}"
                                 BorderThickness="0"
                                 Background="Transparent"
                                 VerticalContentAlignment="Center"
                                 Padding="5"
                                 Foreground="{StaticResource TextBrush}"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

它圆角,更改背景颜色,并删除在您 alt-tabbed 退出并返回应用程序之前选择的虚线。

您表示这是所需的布局:

您当前的代码存在一些问题。首先,使用 DockPanel 托管 TextBlock/TextBox 对,其次,没有控件设置 Grid.IsSharedSizeScope=true。您还为文本框列定义了共享大小,而实际上您只是希望它占用所有可用的 space.

下面是一些实现所需布局的代码:

<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <!--Left hand side content goes here-->
    <StackPanel Orientation="Vertical" Grid.Column="1"
                Grid.RowSpan="2"
                Margin="20,0,0,0"
                Grid.IsSharedSizeScope="True" >
        <StackPanel.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="Grid.Column" Value="0"/>
                <Setter Property="Text" Value="Input Name:"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
        </StackPanel.Resources>


        <Border BorderBrush="Blue" BorderThickness="5">
            <Grid ShowGridLines="True" HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock/>
                <TextBox Grid.Column="1"
                         VerticalAlignment="Center" 
                         Style="{StaticResource FormTextBox}"
                         Margin="5,0,5,0"/>
            </Grid>
        </Border>
        <Border BorderBrush="Red" BorderThickness="5">
            <Grid ShowGridLines="True" HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock/>
                <TextBox Grid.Column="1"
                         VerticalAlignment="Center" 
                         Style="{StaticResource FormTextBox}"
                         Margin="5,0,5,0"/>
            </Grid>
        </Border>
    </StackPanel>
</Grid>

此代码产生:

但实际上,如果您要获得最大的可用性,您会想要为 TextBlock/TextBox 创建自己的控件,然后您可以将它放在某种 ItemsControl 中以实现动态内容.