Каков простой способ установить расстояние между элементами в StackPanel?

есть ли простой способ установить пространство по умолчанию между элементами внутри StackPanel, чтобы мне не нужно было устанавливать свойство Margin для каждого элемента?

3 ответов


если все элементы управления одинаковы, сделайте так, как предложил 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>

полностью многоразовые конечно.


Я использую прозрачный разделитель, который хорошо работает:

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

вы можете, конечно, использовать поля, но затем, если вы хотите изменить поля, вы должны обновить все элементы.

разделитель можно даже стилизовать в статическом ресурсе.

присоединенное свойство тоже может это сделать, но я думаю, что это перебор.


Я считаю, что создание сетки внутри панели стека, а затем добавление необходимого количества столбцов (или строк) следующим образом:

    <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>