设置元素的宽度为容器的其余部分
本文关键字:余部 元素 设置 | 更新日期: 2023-09-27 18:15:48
好吧,这太蠢了!我困惑。我有这个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
似乎不起作用。你知道吗?
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>
Misc:
在你的情况下,我可能不会这样做。如果你的用例是有N行,每行有2列,其中第二列延伸到使用所有剩余的空间,而不是有一个StackPanel
与一堆DockPanel
的每一行里面,你可以做到这一切,只是使用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>
在只使用一个布局容器的情况下会给出相同的输出。
StackPanel
只会和它的内容一样大。
我建议你用DockPanel
替换内部的StackPanel
。DockPanel
的最后一个子元素将填充可用空间(除非您显式地覆盖该行为)。