问题
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?
回答1:
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.
回答2:
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.
回答3:
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>
来源:https://stackoverflow.com/questions/5306029/what-is-the-easy-way-to-set-spacing-between-items-in-stackpanel