给定一个StackPanel:

<StackPanel>
  <TextBox Height="30">Apple</TextBox>
  <TextBox Height="80">Banana</TextBox>
  <TextBox Height="120">Cherry</TextBox>
</StackPanel>

在子元素本身大小不同的情况下,怎样才能使它们之间的间隔大小相等呢?在不为每个单独的子节点设置属性的情况下可以做到这一点吗?


当前回答

UniformGrid可能在Silverlight中无法使用,但有人已经从WPF中移植了它。http://www.jeff.wilcox.name/2009/01/uniform-grid/

其他回答

我改进了埃拉德·卡茨的回答。

为MarginSetter添加LastItemMargin属性以专门处理最后一项 “添加间距”附加属性具有“垂直”和“水平”属性,用于在垂直和水平列表中的项之间添加间距,并消除列表末尾的任何尾距

源代码在主旨。

例子:

<StackPanel Orientation="Horizontal" foo:Spacing.Horizontal="5">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</StackPanel>

<StackPanel Orientation="Vertical" foo:Spacing.Vertical="5">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</StackPanel>

<!-- Same as vertical example above -->
<StackPanel Orientation="Vertical" foo:MarginSetter.Margin="0 0 0 5" foo:MarginSetter.LastItemMargin="0">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</StackPanel>

通常,我使用Grid而不是这样的StackPanel:

水平情况

<Grid>
 <Grid.ColumnDefinitions>
    <ColumnDefinition Width="auto"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition  Width="auto"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition  Width="auto"/>
 </Grid.ColumnDefinitions>
 <TextBox Height="30" Grid.Column="0">Apple</TextBox>
 <TextBox Height="80" Grid.Column="2">Banana</TextBox>
 <TextBox Height="120" Grid.Column="4">Cherry</TextBox>
</Grid>

垂直的情况下

<Grid>
     <Grid.ColumnDefinitions>
        <RowDefinition Width="auto"/>
        <RowDefinition Width="*"/>
        <RowDefinition  Width="auto"/>
        <RowDefinition Width="*"/>
        <RowDefinition  Width="auto"/>
     </Grid.ColumnDefinitions>
     <TextBox Height="30" Grid.Row="0">Apple</TextBox>
     <TextBox Height="80" Grid.Row="2">Banana</TextBox>
     <TextBox Height="120" Grid.Row="4">Cherry</TextBox>
</Grid>

有时你需要设置填充,而不是边距,使项目之间的空间小于默认值

按照Sergey的建议,你可以定义和重用一个完整的Style(使用各种属性设置,包括Margin),而不仅仅是一个Thickness对象:

<Style x:Key="MyStyle" TargetType="SomeItemType">
  <Setter Property="Margin" Value="0,5,0,5" />
  ...
</Style>

...

  <StackPanel>
    <StackPanel.Resources>
      <Style TargetType="SomeItemType" BasedOn="{StaticResource MyStyle}" />
    </StackPanel.Resources>
  ...
  </StackPanel>

注意,这里的技巧是对隐式样式使用样式继承,从一些外部(可能是从外部XAML文件合并的)资源字典中的样式继承。

Sidenote:

首先,我天真地试图使用隐式样式将控件的style属性设置为外部style资源(用键“MyStyle”定义):

<StackPanel>
  <StackPanel.Resources>
    <Style TargetType="SomeItemType">
      <Setter Property="Style" Value={StaticResource MyStyle}" />
    </Style>
  </StackPanel.Resources>
</StackPanel>

这导致VisualStudio 2010立即关闭灾难性失败错误(HRESULT: 0x8000FFFF (E_UNEXPECTED)),描述在https://connect.microsoft.com/VisualStudio/feedback/details/753211/xaml-editor-window-fails-with-catastrophic-failure-when-a-style-tries-to-set-style-property#

网格。列空间网格。StackPanel行空间。间距现在在UWP预览,所有将允许更好地完成这里的要求。

这些属性目前只与Windows 10秋季创作者更新内部SDK可用,但应该使它到最后位!