在StackPanel中设置项目间距的简便方法是什么?

Pom*_*oma 19 c# wpf xaml stackpanel

有没有一种简单的方法在StackPanel内的项目之间设置默认空间,所以我不必在每个项目上设置Margin属性?

key*_*yle 44

我使用透明分隔符,效果很好:

<Separator Opacity="0" Height="20"/>
Run Code Online (Sandbox Code Playgroud)

您当然可以使用边距,但如果您想更改边距,则必须更新所有元素.

分隔符甚至可以在静态资源中设置样式.

附属财产也可以做到,但我认为这有点过分.


Ela*_*atz 13

如果所有控件都相同,那么就像IanR建议的那样,并实现一个捕获该控件的Style.如果不是那么你就不能为基类创建默认样式,因为它不起作用.

这种情况的最佳方法是使用非常巧妙的技巧 - 附加属性(也称为WPF4中的行为)

你可以创建一个具有附加属性的类,如下所示:

public class MarginSetter
{
    public static Thickness GetMargin(DependencyObject obj)
    {
        return (Thickness)obj.GetValue(MarginProperty);
    }

    public static void SetMargin(DependencyObject obj, Thickness value)
    {
        obj.SetValue(MarginProperty, value);
    }

    // Using a DependencyProperty as the backing store for Margin.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MarginProperty =
        DependencyProperty.RegisterAttached("Margin", typeof(Thickness), typeof(MarginSetter), new UIPropertyMetadata(new Thickness(), CreateThicknesForChildren));

    public static void CreateThicknesForChildren(object sender, DependencyPropertyChangedEventArgs e)
    {
        var panel = sender as Panel;

        if (panel == null) return;

        foreach (var child in panel.Children)
        {
            var fe = child as FrameworkElement;

            if (fe == null) continue;

            fe.Margin = MarginSetter.GetMargin(panel);
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

现在,要使用它,您需要做的就是将此附加属性附加到您想要的任何面板,如下所示:

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

完全可重复使用当然.

  • 唯一的问题是它静态工作:如果你在实例化面板后添加/删除子项,那将无法正常工作. (2认同)
  • 您的附加行为可以订阅"LayoutUpdated",并根据需要为新项目设置正确的保证金. (2认同)