有没有一种简单的方法来设置 StackPanel 内部项之间的默认间距,以便我不必在每个项上设置 Margin 属性?
有没有一种简单的方法来设置 StackPanel 内部项之间的默认间距,以便我不必在每个项上设置 Margin 属性?
我使用了一个透明分隔符,效果很好:
<Separator Opacity="0" Height="20"/>
当然,您可以使用边距,但是如果要更改边距,则必须更新所有元素。
分隔符甚至可以在静态资源中进行样式设置。
附加属性也可以实现此目的,但我认为这有些过度了。
如果所有的控件都相同,那么按照IanR的建议实现一个能够捕捉到该控件的样式。否则,你不能为基类创建一个默认样式,因为这样是行不通的。
在这种情况下最好的方法是使用一个非常巧妙的技巧-附加属性(也称为WPF4中的Behaviors)。
你可以创建一个具有附加属性的类,如下所示:
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>
当然完全可重复使用。
LayoutUpdated
,并根据需要为新项设置正确的边距。 - Jens<Rectangle Width="3"/>
<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>
已经接受的答案不再适用。但是我使用了那个答案和那个答案的作者(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>