これが私が使用している例です:
<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"添付プロパティプロバイダーを使用できます。内部コントロールのマージンとパディングを設定する同様の方法はありますか?
これにより、コードが短くなり、パネルの各コントロールに設定する代わりに、マージンとパディングを1回だけ指定できます。
ありがとうございました!
James Hayが提供するソリューション は、希望する結果を得る最も簡単な方法です。
ただし、他の可能な解決策があります:
WrapPanel
および/またはそのすべての子に対してMargin
を設定するPadding
に独自の添付プロパティ/動作を実装できます。詳細は Josh SmithによるこのCodeProjectの記事 を参照してください。WrapPanel
を継承する独自のパネルを作成し、必要なプロパティを追加して適切なメソッドをオーバーライドするだけで、すべての子要素にMargin
/Padding
が設定されます。Style
定義をWindow.Resources
からWrapPanel.Resources
に移動し、x:Key
属性をStyle
から削除して、Style="{StaticResource ButtonStyle}"
すべてのButton
sから。このようにして、Style
は、Button
の子であるallWrapPanel
sに適用されます。子として他のコントロールもある場合は、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>
ただし、これは、直接の子だけでなく、Button
内のallWrapPanel
インスタンスにも影響を与えることに注意してください。
別の素晴らしいアプローチをここで見ることができます: 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>
これは、たとえ同じタイプでなくても、マージンをパネルの複数の子に設定する最も簡単で最速の方法です。 (つまり、ボタン、テキストボックス、コンボボックスなど)
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>
以下は、ItemMargin依存関係プロパティを追加するカスタマイズされたWrapPanelコントロールです。
/// <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>
パネルに項目があまりない場合は、Lineコントロールを使用して、WrapPanelの場合は幅、StackPanelの場合は高さを指定できます。次に、ラインをスタイルします。
<WrapPanel Orientation="Horizontal" >
<Button Content="test1" />
<Line Width="15" />
<Button Content="test2" />
<Line Width="15" />
<Button Content="test3" />
</WrapPanel>