Answers:
使用“边距”或“填充”,将其应用于容器内的范围:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="0,10,0,0"/>
</Style>
</StackPanel.Resources>
<TextBox Text="Apple"/>
<TextBox Text="Banana"/>
<TextBox Text="Cherry"/>
</StackPanel>
编辑:如果您想重复使用两个容器之间的边距,则可以将边距值转换为外部作用域中的资源,例如
<Window.Resources>
<Thickness x:Key="tbMargin">0,10,0,0</Thickness>
</Window.Resources>
然后在内部范围中引用此值
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="{StaticResource tbMargin}"/>
</Style>
</StackPanel.Resources>
Button
。
Label
,你必须使用Padding
替代Margin
可以在此处看到另一种不错的方法:http : //blogs.microsoft.co.il/blogs/eladkatz/archive/2011/05/29/what-is-the-easiest-way-to-set-spacing-between- items-in-stackpanel.aspx 链接已断开-> 此链接是webarchive。
它显示了如何创建附加行为,这样的语法将起作用:
<StackPanel local:MarginSetter.Margin="5">
<TextBox Text="hello" />
<Button Content="hello" />
<Button Content="hello" />
</StackPanel>
这是将“边距”设置为面板的多个子级的最简单,最快的方法,即使它们不是同一类型。(即按钮,文本框,组合框等)
if (fe.ReadLocalValue(FrameworkElement.MarginProperty) == DependencyProperty.UnsetValue)
在实际设置子项的边距之前添加了它,它允许手动为某些元素指定边距。
我改进了埃拉德·卡茨的回答。
例:
<StackPanel Orientation="Horizontal" foo:Spacing.Horizontal="5">
<Button>Button 1</Button>
<Button>Button 2</Button>
</StackPanel>
<StackPanel Orientation="Vertical" foo:Spacing.Vertical="5">
<Button>Button 1</Button>
<Button>Button 2</Button>
</StackPanel>
<!-- Same as vertical example above -->
<StackPanel Orientation="Vertical" foo:MarginSetter.Margin="0 0 0 5" foo:MarginSetter.LastItemMargin="0">
<Button>Button 1</Button>
<Button>Button 2</Button>
</StackPanel>
ItemsControl
绑定到变化的集合中),则此方法将无效。假设从父级Load
事件触发时起这些项是静态的。
您真正想做的是包装所有子元素。在这种情况下,您应该使用项目控件,而不要使用可怕的附加属性,对于要样式化的每个属性,最终将拥有一百万个属性。
<ItemsControl>
<!-- target the wrapper parent of the child with a style -->
<ItemsControl.ItemContainerStyle>
<Style TargetType="Control">
<Setter Property="Margin" Value="0 0 5 0"></Setter>
</Style>
</ItemsControl.ItemContainerStyle>
<!-- use a stack panel as the main container -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- put in your children -->
<ItemsControl.Items>
<Label>Auto Zoom Reset?</Label>
<CheckBox x:Name="AutoResetZoom"/>
<Button x:Name="ProceedButton" Click="ProceedButton_OnClick">Next</Button>
<ComboBox SelectedItem="{Binding LogLevel }" ItemsSource="{Binding LogLevels}" />
</ItemsControl.Items>
</ItemsControl>
Margin="0 0 -5 0"
)的边距中减去间隔的数量也将抵消列表中最后一项之后的间隔。
+1为谢尔盖的答案。如果要将其应用于所有StackPanel,则可以执行以下操作:
<Style TargetType="{x:Type StackPanel}">
<Style.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="{StaticResource tbMargin}"/>
</Style>
</Style.Resources>
</Style>
但要注意:如果您在App.xaml(或合并到Application.Resources中的另一个词典)中定义了这样的样式,则它可以覆盖控件的默认样式。对于像stackpanel这样的大多数看起来不清晰的控件,这不是问题,但是对于文本框等,您可能会偶然发现此问题,幸运的是,它有一些解决方法。
遵循Sergey的建议,您可以定义和重用整个Style(具有各种属性设置器,包括Margin),而不仅是Thickness对象:
<Style x:Key="MyStyle" TargetType="SomeItemType">
<Setter Property="Margin" Value="0,5,0,5" />
...
</Style>
...
<StackPanel>
<StackPanel.Resources>
<Style TargetType="SomeItemType" BasedOn="{StaticResource MyStyle}" />
</StackPanel.Resources>
...
</StackPanel>
请注意,此处的技巧是将样式继承用于隐式样式,该样式继承是从某些外部(可能是从外部XAML文件合并)的资源字典中的样式继承的。
边注:
首先,我天真地尝试使用隐式样式将控件的Style属性设置为该外部Style资源(例如,用键“ MyStyle”定义):
<StackPanel>
<StackPanel.Resources>
<Style TargetType="SomeItemType">
<Setter Property="Style" Value={StaticResource MyStyle}" />
</Style>
</StackPanel.Resources>
</StackPanel>
如https://connect.microsoft.com/VisualStudio/feedback/details/753211/xaml-editor-window-fails中所述,这导致Visual Studio 2010立即关闭,并发生CATASTROPHIC FAILURE错误(HRESULT:0x8000FFFF(E_UNEXPECTED))。尝试设置样式属性时发生灾难性故障#
Grid.ColumnSpacing,Grid.RowSpacing,StackPanel.Spacing现在可以在UWP预览中使用,所有这些都可以更好地完成此处的要求。
这些属性当前仅在Windows 10 Fall Creators Update Insider SDK中可用,但应牢记在心!
UniformGrid可能在Silverlight中不可用,但是有人从WPF移植了它。http://www.jeff.wilcox.name/2009/01/uniform-grid/
我的方法继承了StackPanel。
用法:
<Controls:ItemSpacer Grid.Row="2" Orientation="Horizontal" Height="30" CellPadding="15,0">
<Label>Test 1</Label>
<Label>Test 2</Label>
<Label>Test 3</Label>
</Controls:ItemSpacer>
所需要的只是以下简短的课程:
using System.Windows;
using System.Windows.Controls;
using System;
namespace Controls
{
public class ItemSpacer : StackPanel
{
public static DependencyProperty CellPaddingProperty = DependencyProperty.Register("CellPadding", typeof(Thickness), typeof(ItemSpacer), new FrameworkPropertyMetadata(default(Thickness), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCellPaddingChanged));
public Thickness CellPadding
{
get
{
return (Thickness)GetValue(CellPaddingProperty);
}
set
{
SetValue(CellPaddingProperty, value);
}
}
private static void OnCellPaddingChanged(DependencyObject Object, DependencyPropertyChangedEventArgs e)
{
((ItemSpacer)Object).SetPadding();
}
private void SetPadding()
{
foreach (UIElement Element in Children)
{
(Element as FrameworkElement).Margin = this.CellPadding;
}
}
public ItemSpacer()
{
this.LayoutUpdated += PART_Host_LayoutUpdated;
}
private void PART_Host_LayoutUpdated(object sender, System.EventArgs e)
{
this.SetPadding();
}
}
}