给定一个StackPanel:
<StackPanel>
<TextBox Height="30">Apple</TextBox>
<TextBox Height="80">Banana</TextBox>
<TextBox Height="120">Cherry</TextBox>
</StackPanel>
在子元素本身大小不同的情况下,怎样才能使它们之间的间隔大小相等呢?在不为每个单独的子节点设置属性的情况下可以做到这一点吗?
给定一个StackPanel:
<StackPanel>
<TextBox Height="30">Apple</TextBox>
<TextBox Height="80">Banana</TextBox>
<TextBox Height="120">Cherry</TextBox>
</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文件合并的)资源字典中的样式继承。
Sidenote:
首先,我天真地试图使用隐式样式将控件的style属性设置为外部style资源(用键“MyStyle”定义):
<StackPanel>
<StackPanel.Resources>
<Style TargetType="SomeItemType">
<Setter Property="Style" Value={StaticResource MyStyle}" />
</Style>
</StackPanel.Resources>
</StackPanel>
这导致VisualStudio 2010立即关闭灾难性失败错误(HRESULT: 0x8000FFFF (E_UNEXPECTED)),描述在https://connect.microsoft.com/VisualStudio/feedback/details/753211/xaml-editor-window-fails-with-catastrophic-failure-when-a-style-tries-to-set-style-property#
其他回答
有时你需要设置填充,而不是边距,使项目之间的空间小于默认值
按照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文件合并的)资源字典中的样式继承。
Sidenote:
首先,我天真地试图使用隐式样式将控件的style属性设置为外部style资源(用键“MyStyle”定义):
<StackPanel>
<StackPanel.Resources>
<Style TargetType="SomeItemType">
<Setter Property="Style" Value={StaticResource MyStyle}" />
</Style>
</StackPanel.Resources>
</StackPanel>
这导致VisualStudio 2010立即关闭灾难性失败错误(HRESULT: 0x8000FFFF (E_UNEXPECTED)),描述在https://connect.microsoft.com/VisualStudio/feedback/details/753211/xaml-editor-window-fails-with-catastrophic-failure-when-a-style-tries-to-set-style-property#
网格。列空间网格。StackPanel行空间。间距现在在UWP预览,所有将允许更好地完成这里的要求。
这些属性目前只与Windows 10秋季创作者更新内部SDK可用,但应该使它到最后位!
通常,我使用Grid而不是这样的StackPanel:
水平情况
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox Height="30" Grid.Column="0">Apple</TextBox>
<TextBox Height="80" Grid.Column="2">Banana</TextBox>
<TextBox Height="120" Grid.Column="4">Cherry</TextBox>
</Grid>
垂直的情况下
<Grid>
<Grid.ColumnDefinitions>
<RowDefinition Width="auto"/>
<RowDefinition Width="*"/>
<RowDefinition Width="auto"/>
<RowDefinition Width="*"/>
<RowDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox Height="30" Grid.Row="0">Apple</TextBox>
<TextBox Height="80" Grid.Row="2">Banana</TextBox>
<TextBox Height="120" Grid.Row="4">Cherry</TextBox>
</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();
}
}
}