【问题标题】:How can I anchor a textbox in wpf?如何在 wpf 中锚定文本框?
【发布时间】:2010-05-26 17:11:43
【问题描述】:

我有一个带有标签的窗口。在其中一个选项卡上,我的布局如下所示。 (其实比较复杂,我一行有4个文本框,而且行数更多。)怎样才能让第3个文本框有标签的宽度+上面文本框的宽度,也就是要它们是否正确对齐?问题是当我在其中输入文本时,WPF 会扩大第三个文本框。对大小使用硬编码数字违背了 WPF 的全部目的。在 Windows 窗体中我可以比在 WPF 中快 10 倍。

有没有更好的方法,而不是为每组连续的小文本框使用网格,不得不从网格中跳过大的文本框,因为把它们放在里面会搞砸一切。

<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>

【问题讨论】:

    标签: wpf


    【解决方案1】:

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

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

    就个人而言,我会采用这个解决方案:

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

    【讨论】:

    • 谢谢。将第二列的宽度设置为 * 就可以了。它有一个小故障。我可以使用单个网格,但我需要使用 Width="{Binding ElementName=grid,Path=ActualWidth}" 保留堆栈面板。
    【解决方案2】:
     <TextBox Grid.Row="1" Grid.ColumnSpan="2" /> 
    

    【讨论】:

      【解决方案3】:

      我会有一个有 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>
      

      【讨论】:

      • 这不起作用。在第三个文本框中键入一些文本会使其更宽。
      【解决方案4】:

      只需删除对齐属性:

      HorizontalAlignment="Center" VerticalAlignment="Center" 
      

      例如文本框是:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-22
        • 1970-01-01
        • 1970-01-01
        • 2011-03-29
        • 2012-11-23
        • 1970-01-01
        • 2010-11-13
        • 2012-11-24
        相关资源
        最近更新 更多