如何分隔StackPanel的子元素?

Gra*_*meF 175 silverlight wpf xaml stackpanel

给定StackPanel:

<StackPanel>
  <TextBox Height="30">Apple</TextBox>
  <TextBox Height="80">Banana</TextBox>
  <TextBox Height="120">Cherry</TextBox>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

即使子元素本身具有不同的大小,将子元素间隔开来以使它们之间存在大小相等的间隙的最佳方法是什么?可以在没有为每个孩子设置属性的情况下完成吗?

Ser*_*hov 269

使用Margin或Padding,应用于容器中的范围:

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Margin" Value="0,10,0,0"/>
        </Style>
    </StackPanel.Resources> 
    <TextBox Text="Apple"/>
    <TextBox Text="Banana"/>
    <TextBox Text="Cherry"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

编辑:如果您想重新使用两个容器之间的边距,您可以将边距值转换为外部范围内的资源,fe

<Window.Resources>
    <Thickness x:Key="tbMargin">0,10,0,0</Thickness>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

然后在内部范围中引用此值

<StackPanel.Resources>
    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="{StaticResource tbMargin}"/>
    </Style>
</StackPanel.Resources>
Run Code Online (Sandbox Code Playgroud)

  • 有人可以解释为什么这只有在你明确定义类型(例如TextBox)时才有效吗?如果我使用FrameworkElement尝试这样,以便所有子节点间隔,它没有任何效果. (9认同)
  • 范围风格是*非常棒*的方式来做到这一点 - 感谢小费! (5认同)
  • @DaxFohl目标FrameworkElement似乎不起作用. (3认同)
  • 如果你已经为`Button`定义了一个样式,这不会很好. (3认同)
  • 如果我想将它用于整个项目怎么办? (2认同)
  • 附带说明一下,如果你想用 `Label` 来做到这一点,你必须使用 `Padding` 而不是 `Margin` (2认同)
  • 对于@Mark Ingram 和其他人,请使用 `Style.BaseOn` 属性。`BaseOn="{StaticResource {x:Type Button}}"` 可以使其继承父样式。欲了解更多信息:/sf/ask/3084576841/ (2认同)

Ela*_*atz 82

另一种不错的方法可以在这里看到:http: //blogs.microsoft.co.il/blogs/eladkatz/archive/2011/05/29/what-is-the-easiest-way-to-set-spacing-between-项功能于stackpanel.aspx

它显示了如何创建附加行为,以便像这样的语法可以工作:

<StackPanel local:MarginSetter.Margin="5">
   <TextBox Text="hello" />
   <Button Content="hello" />
   <Button Content="hello" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

这是将边距设置为面板的几个子节点的最简单,最快捷的方法,即使它们的类型不同.(即按钮,文本框,组合框等)

  • 这是一个非常有趣的方式来解决这个问题.它对你想要如何摆放物品做出了很多假设,甚至让你有机会自动调整第一件/最后一件物品的边距. (5认同)
  • 链接已损坏! (3认同)
  • 多功能性+1。为了改善博客文章,在实际设置子项的边距之前添加`if(fe.ReadLocalValue(FrameworkElement.MarginProperty)== DependencyProperty.UnsetValue)`可以手动指定某些元素的边距。 (2认同)

ang*_*sen 14

我改进了Elad Katz的回答.

  • 将LastItemMargin属性添加到MarginSetter以专门处理最后一项
  • 使用垂直和水平属性添加间距附加属性,在垂直和水平列表中添加项目之间的间距,并消除列表末尾的任何尾随边距

gist中的源代码.

例:

<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>
Run Code Online (Sandbox Code Playgroud)


bra*_*ing 9

你真正想要做的是包装所有子元素.在这种情况下,你应该使用一个物品控制,而不是诉诸于可怕的附属物,你最终会为你想要造型的每个物业赚一百万.

<ItemsControl>

    <!-- target the wrapper parent of the child with a style -->
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="Control">
            <Setter Property="Margin" Value="0 0 5 0"></Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>

    <!-- use a stack panel as the main container -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!-- put in your children -->
    <ItemsControl.Items>
        <Label>Auto Zoom Reset?</Label>
        <CheckBox x:Name="AutoResetZoom"/>
        <Button x:Name="ProceedButton" Click="ProceedButton_OnClick">Next</Button>
        <ComboBox SelectedItem="{Binding LogLevel }" ItemsSource="{Binding LogLevels}" />
    </ItemsControl.Items>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


And*_*uus 6

+1为谢尔盖的答案。如果要将其应用于所有StackPanel,则可以执行以下操作:

<Style TargetType="{x:Type StackPanel}">
    <Style.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Margin" Value="{StaticResource tbMargin}"/>
        </Style>
    </Style.Resources>
</Style>
Run Code Online (Sandbox Code Playgroud)

但要注意:如果您在App.xaml(或另一个合并到Application.Resources中的字典)中定义了这样的样式,则它可以覆盖控件的默认样式。对于像stackpanel这样的大多数看起来不清晰的控件,这不是问题,但是对于文本框等,您可能会偶然发现此问题,幸运的是,它有一些解决方法。