我该如何在WPF中锚定文本框?

3
我有一个带选项卡的窗口。在其中一个选项卡上,我有一个如下所示的布局。(实际上更加复杂,我有4个文本框在一行中,而且我有更多的行。)如何使第三个文本框的宽度等于标签的宽度加上上面文本框的宽度,即使它们对齐?问题是当我在第三个文本框中输入文本时,WPF会将其加宽。使用硬编码数字来设置大小会使WPF失去意义。我可以在Windows Forms中以10倍的速度完成这种方式。

是否有更好的方法,而不是为每组连续的小文本框使用网格,并跳过大的文本框,因为将它们放在网格中会搞乱一切。

alt text

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="3"/>
        </Style>
        <Style x:Key="SmallTextBox" TargetType="{x:Type TextBox}"
               BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Width" Value="50"/>
        </Style>
    </Window.Resources>

    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left"
                Width="{Binding ElementName=grid,Path=ActualWidth}"
                Grid.IsSharedSizeScope="True">
        <Grid Name="grid" HorizontalAlignment="Left">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c2"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Label Content="Foo:"/>
            <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
            <Label Grid.Row="1" Content="Foobar:"/>
            <TextBox Grid.Row="1" Grid.Column="1"
                     Style="{StaticResource SmallTextBox}"/>
        </Grid>

        <TextBox Grid.Row="1"/>

        <Grid Name="grid2" HorizontalAlignment="Left">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c2"/>
            </Grid.ColumnDefinitions>

            <Label Content="Bar:"/>
            <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
        </Grid>
    </StackPanel>
</Window>

编辑:这是基于Julien Lebosquain答案的解决方案:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Margin" Value="3"/>
        </Style>
        <Style x:Key="SmallTextBox" TargetType="{x:Type TextBox}"
               BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Width" Value="50"/>
        </Style>
    </Window.Resources>

    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left"
                Width="{Binding ElementName=grid,Path=ActualWidth}">
        <Grid Name="grid">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Label Content="Foo:"/>
            <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
            <Label Grid.Row="1" Content="Foobar:"/>
            <TextBox Grid.Row="1" Grid.Column="1"
                     Style="{StaticResource SmallTextBox}"/>
            <TextBox Grid.Row="2" Grid.ColumnSpan="2"/>
            <Label Grid.Row="3" Content="Bar:"/>
            <TextBox Grid.Row="3" Grid.Column="1"
                     Style="{StaticResource SmallTextBox}"/>
        </Grid>
    </StackPanel>
</Window>
4个回答

1

我认为你弄反了。并不是最大的文本框搞砸了一切,而是小文本框具有固定大小使它们不像最大的那个。你在这里存在矛盾:使用堆栈面板,其意味着“采用我的子项的宽度”,Width=Auto 具有相同的行为,但你不想让你的堆栈面板增长。

在视觉树中更高的位置上,你需要指定一个宽度或使用一个控件,其尺寸行为是占据整个空间,比如 Grid。

就我个人而言,我会选择以下解决方案:

  • 仅使用一个内部表格,小文本框不再具有固定大小,而大文本框具有 Grid.ColumnSpan="2"
  • Width="Auto" 应用于第一列,将 Width="*" 应用于第二列。
  • 用第一列固定或星号大小的 Grid 替换现有的 StackPanel(以便在调整窗口大小时它会缩放)。将内部网格放在此第一列中。

谢谢。将第二列的宽度设置为*就解决了问题。虽然有一点小问题,但它可以使用单个网格,但我需要保留StackPanel,并使用Width="{Binding ElementName=grid,Path=ActualWidth}"。 - Jeno Csupor

0

只需删除对齐属性:

HorizontalAlignment="Center" VerticalAlignment="Center" 

例如,文本框将是:

<TextBox x:Name="txtMyName1" Margin="3" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox x:Name="txtMyName2" Margin="3" />

0

我会有一个具有4行的网格。并在第3行上设置ColumnSpan。这也意味着您不需要SharedSizeGroups。

<Grid Name="grid" HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Label Content="Foo:"/>
        <TextBox Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
        <Label Grid.Row="1" Content="Foobar:"/>
        <TextBox Grid.Row="1" Grid.Column="1"
                 Style="{StaticResource SmallTextBox}"/>

        <TextBox Grid.Row="2" Grid.ColumnSpan="2" />

        <Label Content="Bar:"/>
        <TextBox Grid.Row="3" Grid.Column="1" Style="{StaticResource SmallTextBox}"/>
    </Grid>

这不起作用。在第三个文本框中输入一些文本会使它变宽。 - Jeno Csupor

0
 <TextBox Grid.Row="1" Grid.ColumnSpan="2" /> 

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