以下是我正在使用的示例:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<WrapPanel Orientation="Horizontal" TextElement.FontSize="30" TextElement.FontStyle="Italic" >
<Button Content="test1" Margin="10,0" Padding="10,10" />
<Button Content="test2" Margin="10,0" Padding="10,10" />
<Button Content="test3" Margin="10,0" Padding="10,10" />
<Button Content="test4" Margin="10,0" Padding="10,10" />
<Button Content="test5" Margin="10,0" Padding="10,10" />
</WrapPanel>
</StackPanel>
如您所见,我的包装面板有几个按钮。 每个按钮都有相同的边距和填充。
问题是,有没有办法为包装面板设置边距和填充,因此包装面板中的每个元素都可以使用它的值?
为了设置内部元素的字体,我可以使用“TextElement”附加属性提供程序。有没有类似的方法我可以为内部控件设置边距和填充?
这会缩短代码,让我只指定一次Margin和Padding,而不是为面板中的每个控件设置它。
谢谢!
答案 0 :(得分:22)
The solution provided by James Hay是达到理想效果的最简单方法。
但是,还有其他可能的解决方案:
WrapPanel
实施自己的附加属性/行为,为其所有子项设置Margin
和/或Padding
。有关详细信息,请参阅this CodeProject article by Josh Smith。WrapPanel
,只需添加所需的属性并覆盖相应的方法,以便为所有子元素设置Margin
/ Padding
。 Style
定义从Window.Resources
移至WrapPanel.Resources
,从x:Key
移除Style
属性,然后移除{{来自所有Style="{StaticResource ButtonStyle}"
的1}}。这样,Button
就会应用于所有 Style
,它们是Button
的子项。如果您还有其他控件作为子级,则可以将WrapPanel
的{{1}}更改为适当的公共基本类型(例如TargetType
):
Style
但请注意,这会影响FrameworkElement
内的所有 <StackPanel>
<WrapPanel Orientation="Horizontal">
<WrapPanel.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10,0" />
<Setter Property="Padding" Value="10,10" />
</Style>
</WrapPanel.Resources>
<Button Content="test1" />
<Button Content="test2" />
<Button Content="test3" />
<Button Content="test4" />
<Button Content="test5" />
</WrapPanel>
</StackPanel>
个实例,而不仅仅是其直接的孩子!
答案 1 :(得分:17)
这里可以看到另一种不错的方法: http://blogs.microsoft.co.il/blogs/eladkatz/archive/2011/05/29/what-is-the-easiest-way-to-set-spacing-between-items-in-stackpanel.aspx
它显示了如何创建附加行为,以便像这样的语法可以工作:
<StackPanel local:MarginSetter.Margin="5">
<TextBox Text="hello" />
<Button Content="hello" />
<Button Content="hello" />
</StackPanel>
这是最简单的&amp;将边距设置为面板的几个子节点的最快方法,即使它们的类型不同。 (即按钮,文本框,组合框等)
答案 2 :(得分:7)
WrapPanel没有任何为其所有子项添加填充或边距的属性。您可能想要的是每个按钮共享的样式。类似的东西:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10,0" />
<Setter Property="Padding" Value="10,10" />
</Style>
</Window.Resources>
<StackPanel>
<WrapPanel Orientation="Horizontal" >
<Button Content="test1" Style="{StaticResource ButtonStyle}" />
<Button Content="test2" Style="{StaticResource ButtonStyle}" />
<Button Content="test3" Style="{StaticResource ButtonStyle}" />
<Button Content="test4" Style="{StaticResource ButtonStyle}" />
<Button Content="test5" Style="{StaticResource ButtonStyle}" />
</WrapPanel>
</StackPanel>
</Window>
答案 3 :(得分:2)
这是一个自定义的WrapPanel控件,它添加了一个ItemMargin依赖项属性。
/// <summary>
/// A wrap panel which can apply a margin to each child item.
/// </summary>
public class ItemMarginWrapPanel : WrapPanel
{
/// <summary>
/// ItemMargin static DP.
/// </summary>
public static readonly DependencyProperty ItemMarginProperty =
DependencyProperty.Register(
"ItemMargin",
typeof( Thickness ),
typeof( ItemMarginWrapPanel ),
new FrameworkPropertyMetadata(
new Thickness(),
FrameworkPropertyMetadataOptions.AffectsMeasure ) );
/// <summary>
/// The margin that will be applied to each Item in the wrap panel.
/// </summary>
public Thickness ItemMargin
{
get
{
return (Thickness)GetValue( ItemMarginProperty );
}
set
{
SetValue( ItemMarginProperty, value );
}
}
/// <summary>
/// Overridden. Sets item margins before calling base implementation.
/// </summary>
/// <param name="constraint"></param>
/// <returns></returns>
protected override Size MeasureOverride( Size constraint )
{
RefreshItemMargin();
return base.MeasureOverride( constraint );
}
/// <summary>
/// Overridden. Sets item margins before calling base implementation.
/// </summary>
/// <param name="finalSize"></param>
/// <returns></returns>
protected override Size ArrangeOverride( Size finalSize )
{
RefreshItemMargin();
return base.ArrangeOverride( finalSize );
}
/// <summary>
/// Refresh the child item margins.
/// </summary>
private void RefreshItemMargin()
{
var children = InternalChildren;
for( int i = 0, count = children.Count; i < count; i++ )
{
var ele = children[i] as FrameworkElement;
if( null != ele )
ele.Margin = ItemMargin;
}
}
}
现在你可以这样做:
<Style
x:Key="MarginWrapPanelStyle"
TargetType="{x:Type mycustomcontrols:ItemMarginWrapPanel}">
<Setter
Property="ItemMargin"
Value="5" />
</Style>
答案 4 :(得分:0)
如果面板中的项目不多,您可以使用Line控件,并在StackPanel的情况下为WrapPanel和高度赋予宽度。然后你可以设置Line的样式。
<WrapPanel Orientation="Horizontal" >
<Button Content="test1" />
<Line Width="15" />
<Button Content="test2" />
<Line Width="15" />
<Button Content="test3" />
</WrapPanel>