如何在wpf中锚定文本框?

时间:2010-05-26 17:11:44

标签: wpf

我有一个带标签的窗口。在其中一个标签上,我有一个如下所示的布局。 (实际上它更复杂,我连续有4个文本框,而且我有更多行。)如何让第3个文本框具有标签的宽度+上面文本框的宽度,即让它们正确对齐?问题是当我在其中键入文本时,WPF会扩展第3个文本框。使用硬编码的数字会破坏WPF的全部目的。我可以在Windows窗体中以比WPF快10倍的速度。

是否有更好的方法,比为每组连续的小文本框使用网格,不得不跳过网格中的大文本,因为将它们弄乱了所有内容。

alt text http://img28.imageshack.us/img28/3958/wpfanchor.png

<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 个答案:

答案 0 :(得分:1)

我认为你倒退了。这不是最糟糕的文本框。事实上,小文本框具有固定的大小,使它们不像最大的文本框。你在这里有一个矛盾:使用堆栈面板意味着“占用我孩子的宽度”,Width=Auto具有相同的行为,但你不希望你的堆栈面板增长。

在可视化树中较高的位置,您需要指定宽度或使用控件,其大小调整行为将占据整个空间,如Grid。

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

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

答案 1 :(得分:0)

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

答案 2 :(得分: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>

答案 3 :(得分:0)

只需删除对齐属性:

const createUpdateCommon = (next) => {/*check if thrown DuplicateKey error*/}

schema.pre('save', createUpdateCommon);
schema.pre('findOneAndUpdate', createUpdateCommon);

例如,文本框为:

HorizontalAlignment="Center" VerticalAlignment="Center"