201

StackPanelが与えられた場合:

<StackPanel>
  <TextBox Height="30">Apple</TextBox>
  <TextBox Height="80">Banana</TextBox>
  <TextBox Height="120">Cherry</TextBox>
</StackPanel>

子要素自体のサイズが異なっていても、子要素の間に同じサイズのギャップができるように、子要素の間隔を空けるための最良の方法は何ですか?個々の子のそれぞれにプロパティを設定せずに実行できますか?

4

11 に答える 11

310

コンテナ内のスコープに適用される Margin または Padding を使用します。

<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>

編集: 2 つのコンテナー間のマージンを再利用する場合は、マージン値を外部スコープのリソース fe に変換できます。

<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>
于 2009-05-31T18:39:46.803 に答える
95

別の優れたアプローチをここで見ることができます 。 items-in-stackpanel.aspx リンクが壊れています ->これはこのリンクの webarchiveです。

次のような構文が機能するように、添付された動作を作成する方法を示します。

<StackPanel local:MarginSetter.Margin="5">
   <TextBox Text="hello" />
   <Button Content="hello" />
   <Button Content="hello" />
</StackPanel>

これは、同じタイプでなくても、パネルの複数の子に Margin を設定する最も簡単で最速の方法です。(つまり、ボタン、テキストボックス、コンボボックスなど)

于 2011-05-29T22:29:12.317 に答える
9

本当にやりたいことは、すべての子要素をラップすることです。この場合、項目コントロールを使用し、スタイルを設定したいプロパティごとに何百万ものプロパティを持ってしまう恐ろしい添付プロパティに頼らないでください。

<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>

ここに画像の説明を入力

于 2015-06-16T10:18:32.407 に答える
6

セルゲイの答えに+1。そして、それをすべての StackPanels に適用したい場合は、これを行うことができます:

<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 にマージされる別の辞書) でこのようなスタイルを定義すると、コントロールの既定のスタイルがオーバーライドされる可能性があります。スタック パネルのような見た目のほとんどないコントロールでは問題ありませんが、テキスト ボックスなどでは、この問題に出くわす可能性があります。幸いなことに、いくつかの回避策があります。

于 2010-06-23T13:46:58.653 に答える
3

Sergey の提案に従って、Thickness オブジェクトだけでなく、Style 全体 (Margin を含むさまざまなプロパティ セッターを使用) を定義して再利用できます。

<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>

ここでの秘訣は、暗黙的なスタイルに Style Inheritance を使用し、外部の (おそらく外部 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 が壊滅的な障害エラー (HRESULT: 0x8000FFFF (E_UNEXPECTED)) で即座にシャットダウンされました。 -with-catastrophic-failure-when-a-style-tries-to-set-style-property#

于 2012-07-11T10:15:45.527 に答える
3

Grid.ColumnSpacingGrid.RowSpacingStackPanel.Spacingは現在 UWP プレビューにあり、すべてがここで要求されていることをより適切に達成できるようになります。

これらのプロパティは現在、Windows 10 Fall Creators Update Insider SDK でのみ利用できますが、最終的には利用できるようになるはずです!

于 2017-07-06T15:17:59.990 に答える
2

私のアプローチは 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();
        }
    }
}
于 2016-04-16T00:14:07.160 に答える
2

UniformGrid は Silverlight では使用できない可能性がありますが、誰かが WPF から移植しています。http://www.jeff.wilcox.name/2009/01/uniform-grid/

于 2009-05-31T18:22:27.097 に答える
0

アイテム間のスペースをデフォルトよりも小さくするために、マージンではなくパディングを設定する必要がある場合があります

于 2013-11-25T13:41:01.023 に答える