2013-05-29 69 views
1

好吧,这太愚蠢了!我很困惑。我有这个xaml将元素的宽度设置为容器的其余部分

<StackPanel Style="{DynamicResource FormPanel}"> 
     <StackPanel> 
      <Label Content="{DynamicResource Label_FirstName}" 
        Target="{Binding ElementName=FirstName}"/> 
      <TextBox x:Name="FirstName" /> 
     </StackPanel> 
     <StackPanel> 
      <Label Content="{DynamicResource Label_LastName}" 
        Target="{Binding ElementName=LastName}"/> 
      <TextBox x:Name="LastName" /> 
     </StackPanel> 
     <!-- and so one... for each row, I have a StackPanel and a Label and Textbox in it --> 
    </StackPanel> 

而这种风格:

<Style x:Key="FormPanel" TargetType="{x:Type StackPanel}"> 
    <Setter Property="Orientation" Value="Vertical"/> 
    <Setter Property="HorizontalAlignment" Value="Stretch" /> 
    <Style.Resources> 
     <Style TargetType="{x:Type StackPanel}"> 
      <Setter Property="Orientation" Value="Horizontal" /> 
      <Setter Property="HorizontalAlignment" Value="Stretch" /> 
      <Setter Property="Margin" Value="10"/> 
      <Style.Resources> 
       <Style TargetType="{x:Type Label}"> 
        <Setter Property="Width" Value="140"/> 
       </Style> 
       <Style TargetType="{x:Type TextBox}"> 
        <!-- this line doesn't affect --> 
        <Setter Property="HorizontalAlignment" Value="Stretch"/> 
       </Style> 
      </Style.Resources> 
     </Style> 
    </Style.Resources> 
</Style> 

我想设置的TextBox.Width到容器的(StackPanel)宽度的其余部分。在这种情况下,HorizontalAlignment = Stretch不起作用。你有什么想法吗?

回答

1

StackPanel只分配所需的子元素比什么是可用的空间。你需要的是一个DockPanel

看看This对同一主题的一些详细的解释。

您可以修改代码以类似:

<Style x:Key="FormPanel" 
     TargetType="{x:Type StackPanel}"> 
    <Setter Property="Orientation" 
      Value="Vertical" /> 
    <Setter Property="HorizontalAlignment" 
      Value="Stretch" /> 
    <Style.Resources> 
    <Style TargetType="{x:Type DockPanel}"> 
     <Setter Property="HorizontalAlignment" 
       Value="Stretch" /> 
     <Setter Property="Margin" 
       Value="10" /> 
     <Setter Property="LastChildFill" 
       Value="True" /> 
     <Style.Resources> 
     <Style TargetType="{x:Type Label}"> 
      <Setter Property="Width" 
        Value="140" /> 
     </Style> 
     </Style.Resources> 
    </Style> 
    </Style.Resources> 
</Style> 

用法:

<StackPanel Style="{DynamicResource FormPanel}"> 
    <DockPanel> 
    <Label Content="{DynamicResource Label_FirstName}" 
      Target="{Binding ElementName=FirstName}" /> 
    <TextBox x:Name="FirstName" /> 
    </DockPanel> 
    <DockPanel> 
    <Label Content="{DynamicResource Label_LastName}" 
      Target="{Binding ElementName=LastName}" /> 
    <TextBox x:Name="LastName" /> 
    </DockPanel> 
    <!-- and so one... for each row, I have a StackPanel and a Label and Textbox in it --> 
</StackPanel> 

其他:

在你的情况我可能无法做到这一点,虽然。如果你的使用情况是让每一个具有2列,其中第二列延伸到每行使用所有剩余空间,而不是有一个StackPanel有一堆DockPanel的里面N行,你可以只使用一个做这一切Grid

类似:

<Grid Margin="5"> 
    <Grid.Resources> 
    <Style TargetType="{x:Type Label}"> 
     <Setter Property="Margin" 
       Value="5" /> 
    </Style> 
    <Style TargetType="{x:Type TextBox}"> 
     <Setter Property="Margin" 
       Value="5" /> 
    </Style> 
    </Grid.Resources> 
    <Grid.ColumnDefinitions> 
    <ColumnDefinition Width="140" /> 
    <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
    <RowDefinition Height="Auto" /> 
    <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Label Grid.Row="0" 
      Grid.Column="0" 
      Content="{DynamicResource Label_FirstName}" 
      Target="{Binding ElementName=FirstName}" /> 
    <TextBox x:Name="FirstName" 
      Grid.Row="0" 
      Grid.Column="1" /> 
    <Label Grid.Row="1" 
      Grid.Column="0" 
      Content="{DynamicResource Label_LastName}" 
      Target="{Binding ElementName=LastName}" /> 
    <TextBox x:Name="LastName" 
      Grid.Row="1" 
      Grid.Column="1" /> 
</Grid> 

会给你只用1布局容器相同的输出。

+0

完善建议:d –

+0

@Javad_Amiry我已经编辑我的答案有一个“杂项”部分,如果它直接应用,这可能是为你的使用情况较好。只需一个就可以完成你所需要的任务,从而避免使用过多的布局容器。 – Viv

+0

那么,表单有许多行 - 问题示例只显示其中的2个 - 我必须定义大量的RowDefinition。另外,我必须为每个控件设置'Grid.Row'和'Grid.Column',这意味着如果我想重新定位一行,我必须改变很多控件的位置。但我同意你的看法,“网格”似乎是一个更好的容器。对上述问题有任何想法吗? –

0

StackPanel只会大如它的内容。

我建议你用DockPanel更换内StackPanelDockPanel的最后一个孩子将填充可用空间(除非您显式覆盖该行为)。

相关问题