Wpf 如何设置WrapPanel内部控制的余量
下面是我正在使用的一个示例:Wpf 如何设置WrapPanel内部控制的余量,wpf,wpf-controls,Wpf,Wpf Controls,下面是我正在使用的一个示例: <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"> <St
<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”附加属性提供程序。是否有类似的方法可以设置内部控件的边距和填充
这使得代码更短,并且只允许我指定一次边距和填充,而不是为面板中的每个控件设置边距和填充
谢谢大家! 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>
是实现所需结果的最简单方法
但是,还有其他可能的解决方案:
WrapPanel
实现自己附加的属性/行为,该属性/行为为其所有子项设置边距
和/或填充
。有关详细信息,请参阅WrapPanel
,只需添加所需的属性并覆盖适当的方法,以便为所有子元素设置Margin
/Padding
样式定义从窗口.Resources
移动到WrapPanel.Resources
,从样式中删除x:Key
属性,从所有按钮中删除样式=“{StaticResource ButtonStyle}”
。通过这种方式,样式
将应用于所有按钮
s,这些按钮是WrapPanel
的子按钮。如果您还有其他控件作为子控件,则可以将样式的TargetType
更改为适当的通用基本类型(例如FrameworkElement
):
但是,请注意,这将影响
包装程序
中的所有按钮
实例,而不仅仅是其直接子项 这里可以看到另一个不错的方法:
它显示了如何创建附加的行为,以便这样的语法可以工作:
<StackPanel local:MarginSetter.Margin="5">
<TextBox Text="hello" />
<Button Content="hello" />
<Button Content="hello" />
</StackPanel>
这是为面板的几个子级设置边距的最简单和最快速的方法,即使它们不是同一类型。(即按钮、文本框、组合框等)如果面板中的项目不多,您可以使用行控件,并为其指定宽度(如果是WrapPanel)和高度(如果是StackPanel)。然后你就可以设计线条了
<WrapPanel Orientation="Horizontal" >
<Button Content="test1" />
<Line Width="15" />
<Button Content="test2" />
<Line Width="15" />
<Button Content="test3" />
</WrapPanel>
这里是一个自定义的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;
}
}
}
//
///可以对每个子项应用边距的环绕面板。
///
公共类ItemMarginWrapPanel:WrapPanel
{
///
///ItemMargin静态DP。
///
公共静态只读从属属性ItemMarginProperty=
从属属性。寄存器(
“项目边际”,
类型(厚度),
类型(ItemMarginWrapPanel),
新框架属性元数据(
新厚度(),
FrameworkPropertyMetadataOptions.AffectsMeasure));
///
///将应用于“包裹”面板中每个项目的边距。
///
公共页边距
{
得到
{
返回(厚度)GetValue(ItemMarginProperty);
}
设置
{
设置值(ItemMarginProperty,值);
}
}
///
///重写。在调用基本实现之前设置项目边距。
///
///
///
受保护的覆盖尺寸测量覆盖(尺寸约束)
{
RefreshItemMargin();
返回基准。测量超越(约束);
}
///
///重写。在调用基本实现之前设置项目边距。
///
///
///
受保护的替代尺寸排列替代(尺寸最终化)
{
RefreshItemMargin();
返回基数。安排覆盖(最终化);
}
///
///刷新子项边距。
///
私有void RefreshItemMargin()
{
var children=内部子代;
for(int i=0,count=children.count;i
现在,您只需执行以下操作:
<Style
x:Key="MarginWrapPanelStyle"
TargetType="{x:Type mycustomcontrols:ItemMarginWrapPanel}">
<Setter
Property="ItemMargin"
Value="5" />
</Style>
这不是我真正需要的。我刚刚更新了一个示例,并添加了TextElement.FontSize和TextElement.FontStyle属性的用法。我需要类似的方式,但设置边距和填充。还有吗?进一步说(#3)-如果要在WrapPanel中的所有元素上设置样式,请删除TargetType声明,并将Setter更改为包含属性的“Control.”。例如:如果我这样做,VS会抱怨字典中的所有项都必须有一个键,如果我添加键,则样式不会应用于任何内容。第三个解决方案对我来说似乎更优雅/简单,我非常喜欢它!不幸的是,如果您设置了自定义按钮样式,这就不起作用了,如下所示:这是预期的行为,因为WPF总是采用与所讨论的元素“最接近”的属性值。这意味着,因为在元素本身上应用样式,WPF不考虑在某些代码>资源“< /Cord>”节中设置的样式,树中的某些级别更高。我会选择其他方法之一。在.nic中有一个选项#1的示例
<Style
x:Key="MarginWrapPanelStyle"
TargetType="{x:Type mycustomcontrols:ItemMarginWrapPanel}">
<Setter
Property="ItemMargin"
Value="5" />
</Style>