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

发布于 2024-10-21 19:57:30 字数 69 浏览 1 评论 0原文

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

Is there an easy way to set default space between items inside StackPanel so I'll don't have to set Margin property on each item?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅语花开 2024-10-28 19:57:30

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

<Separator Opacity="0" Height="20"/>

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

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

附属财产也可以做到这一点,但我认为这是矫枉过正。

I use a transparent separator, which works well:

<Separator Opacity="0" Height="20"/>

You can of course use margins but then if you want to change the margins you have to update all of the elements.

The separator can even be styled in a static resource.

An attached property could do it too but I think it's overkill.

橘香 2024-10-28 19:57:30

如果所有控件都相同,则按照 IanR 建议执行并实现捕获该控件的样式。如果不是,那么您无法为基类创建默认样式,因为它不起作用。

对于此类情况,最好的方法是使用一个非常巧妙的技巧 - 附加属性(又名 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);
        }
    }


}

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

<StackPanel local:MarginSetter.Margin="10">
    <Button Content="hello " />
    <Button Content="hello " />
    <Button Content="hello " />
    <Button Content="hello " />
</StackPanel>

当然完全可重用。

if all the controls are the same then do as IanR suggested and implement a Style that catches that control. if it's not then you can't create a default style to a base class because it just won't work.

the best way for situations like these is to use a very neat trick - attached properties (aka Behaviors in WPF4)

you can create a class that has an attached property, like so:

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);
        }
    }


}

now, to use it, all you need to do is to attach this attached property to any panel you want, like so:

<StackPanel local:MarginSetter.Margin="10">
    <Button Content="hello " />
    <Button Content="hello " />
    <Button Content="hello " />
    <Button Content="hello " />
</StackPanel>

Completely reusable of course.

此岸叶落 2024-10-28 19:57:30
<Rectangle Width="3"/>
<Rectangle Width="3"/>
单身情人 2024-10-28 19:57:30

我发现在堆栈面板内创建一个网格,然后添加所需的列数(或行数),如下所示:

    <StackPanel Grid.Row="1" Grid.Column="0" Height="34" Width="698" Margin="10,5,10,10" Orientation="Horizontal"  HorizontalAlignment="Center" VerticalAlignment="Center" >
        <Grid Width="698" Margin="0,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="StartButton" Content="Start" Grid.Row="0" Grid.Column="0" Style="{StaticResource 3DButton}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="70" Click="StartButton_Click" />
            <Button x:Name="HelpButton"  Content="Help"  Grid.Row="0" Grid.Column="1" Style="{StaticResource 3DButton}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="70" Click="HelpButton_Click"  />
            <Button x:Name="ExitButton"  Content="Exit"  Grid.Row="0" Grid.Column="2" Style="{StaticResource 3DButton}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="70" Click="ExitButton_Click" Foreground="Red" />
        </Grid>
    </StackPanel>

I find that creating a grid inside the stack panel, then adding the desired number of columns (or rows) as follows:

    <StackPanel Grid.Row="1" Grid.Column="0" Height="34" Width="698" Margin="10,5,10,10" Orientation="Horizontal"  HorizontalAlignment="Center" VerticalAlignment="Center" >
        <Grid Width="698" Margin="0,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="StartButton" Content="Start" Grid.Row="0" Grid.Column="0" Style="{StaticResource 3DButton}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="70" Click="StartButton_Click" />
            <Button x:Name="HelpButton"  Content="Help"  Grid.Row="0" Grid.Column="1" Style="{StaticResource 3DButton}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="70" Click="HelpButton_Click"  />
            <Button x:Name="ExitButton"  Content="Exit"  Grid.Row="0" Grid.Column="2" Style="{StaticResource 3DButton}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="70" Click="ExitButton_Click" Foreground="Red" />
        </Grid>
    </StackPanel>
灰色世界里的红玫瑰 2024-10-28 19:57:30

接受的答案不再有效。但我使用该答案和该答案的作者(Elad Katz)的博客来制作一个工作代码(在 .Net Core 中测试),我在此处复制:

    public static class EstablecedorMargen { 


    public static Thickness GetMargen(DependencyObject objeto) => objeto != null ? (Thickness)objeto.GetValue(PropiedadMargen) : new Thickness();

    public static void SetMargen(DependencyObject objeto, Thickness value) => objeto?.SetValue(PropiedadMargen, value);

    public static readonly DependencyProperty PropiedadMargen 
        = DependencyProperty.RegisterAttached("Margen", typeof(Thickness), typeof(EstablecedorMargen), new UIPropertyMetadata(new Thickness(), Cambió));


    public static void Cambió(object sender, DependencyPropertyChangedEventArgs e) {
        if (!(sender is Panel panel)) return;
        panel.Loaded += new RoutedEventHandler(EstablecerMargenControlesHijos);
    } 


    public static void EstablecerMargenControlesHijos(object sender, RoutedEventArgs e) {

        if (!(sender is Panel panel)) return;
        foreach (var hijo in panel.Children) {
            if (!(hijo is FrameworkElement feHijo)) continue;
            feHijo.Margin = GetMargen(panel);
        }

    } 


} 

然后您使用:

   <StackPanel local:EstablecedorMargen.Margen="10" >          
            <Button Content="1" />
            <Button Content="2" />
            <Button Content="3" />
    </StackPanel>

The accepted answer doesn't work anymore. But I used that answer and the blog the author of that answer (Elad Katz) to make a working code (tested in .Net Core) that I reproduce here:

    public static class EstablecedorMargen { 


    public static Thickness GetMargen(DependencyObject objeto) => objeto != null ? (Thickness)objeto.GetValue(PropiedadMargen) : new Thickness();

    public static void SetMargen(DependencyObject objeto, Thickness value) => objeto?.SetValue(PropiedadMargen, value);

    public static readonly DependencyProperty PropiedadMargen 
        = DependencyProperty.RegisterAttached("Margen", typeof(Thickness), typeof(EstablecedorMargen), new UIPropertyMetadata(new Thickness(), Cambió));


    public static void Cambió(object sender, DependencyPropertyChangedEventArgs e) {
        if (!(sender is Panel panel)) return;
        panel.Loaded += new RoutedEventHandler(EstablecerMargenControlesHijos);
    } 


    public static void EstablecerMargenControlesHijos(object sender, RoutedEventArgs e) {

        if (!(sender is Panel panel)) return;
        foreach (var hijo in panel.Children) {
            if (!(hijo is FrameworkElement feHijo)) continue;
            feHijo.Margin = GetMargen(panel);
        }

    } 


} 

Then you use:

   <StackPanel local:EstablecedorMargen.Margen="10" >          
            <Button Content="1" />
            <Button Content="2" />
            <Button Content="3" />
    </StackPanel>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文