문제

스택 패널이 주어진다 :

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

아동 요소 자체가 크기가 다르더라도 아동 요소를 공간에 공간을 공간화하는 가장 좋은 방법은 무엇입니까? 각 어린이의 속성을 설정하지 않고 수행 할 수 있습니까?

도움이 되었습니까?

해결책

컨테이너 내의 범위에 적용되는 여백 또는 패딩을 사용하십시오.

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

편집 : 두 컨테이너 사이의 여백을 재사용하려면 마진 값을 외부 범위 인 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>

다른 팁

또 다른 멋진 접근 방식은 여기에서 볼 수 있습니다.http://blogs.microsoft.co.il/blogs/eladkatz/archive/2011/05/29/what-is-seaseimes-way-to-set-spacing-betwen-in-stackpanel.aspx

첨부 된 동작을 만드는 방법을 보여 주므로 이와 같은 구문이 작동합니다.

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

이것은 같은 유형이 아닌 경우에도 패널의 여러 어린이에게 여백을 설정하는 가장 쉽고 빠른 방법입니다. (즉, 버튼, 텍스트 상자, 콤보해스 등)

나는 개선했다 Elad Katz의 대답.

  • 마지막 항목을 특별히 처리하기 위해 marginsetter에 ostiTemmargin 속성을 추가하십시오.
  • 수직 및 수평 목록의 항목 사이에 간격을 추가하고 목록 끝의 후행 여백을 제거하는 수직 및 수평 특성으로 간격 부착 특성을 추가합니다.

GIST의 소스 코드.

예시:

<StackPanel Orientation="Horizontal" foo:Spacing.Horizontal="5">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</StackPanel>

<StackPanel Orientation="Vertical" foo:Spacing.Vertical="5">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</StackPanel>

<!-- Same as vertical example above -->
<StackPanel Orientation="Vertical" foo:MarginSetter.Margin="0 0 0 5" foo:MarginSetter.LastItemMargin="0">
  <Button>Button 1</Button>
  <Button>Button 2</Button>
</StackPanel>

당신이 정말로하고 싶은 것은 모든 어린이 요소를 감싸는 것입니다. 이 경우 항목 컨트롤을 사용해야하며 끔찍한 첨부 된 속성에 의지하지 않아야합니다.

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

enter image description here

Sergey의 답변에 대한 +1. 그리고 모든 스택 패널에 적용하려면 다음을 수행 할 수 있습니다.

<Style TargetType="{x:Type StackPanel}">
    <Style.Resources>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Margin" Value="{StaticResource tbMargin}"/>
        </Style>
    </Style.Resources>
</Style>

그러나 조심하십시오 : app.xaml (또는 응용 프로그램에 병합되는 다른 사전)에서 이와 같은 스타일을 정의하는 경우 it ~할 수 있다 컨트롤의 기본 스타일을 무시하십시오. StackPanel과 같은 대부분의 룩친 컨트롤의 경우 문제가되지 않지만 텍스트 상자 등의 경우 우연히 발견 할 수 있습니다. 이 문제, 운 좋게도 해결 방법이 있습니다.

Sergey의 제안에 따라 두께 객체 대신 전체 스타일 (여백을 포함한 다양한 속성 세터 포함)을 정의하고 재사용 할 수 있습니다.

<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 파일에서 병합 된) 리소스 사전에서 스타일에서 상속됩니다.

사이드 노트 :

처음에, 나는 컨트롤의 스타일 속성을 해당 외부 스타일 자원으로 설정하기 위해 암시 적 스타일을 사용하려고 시도했습니다 (예 : 키 "mystyle"으로 정의 됨) :

<StackPanel>
  <StackPanel.Resources>
    <Style TargetType="SomeItemType">
      <Setter Property="Style" Value={StaticResource MyStyle}" />
    </Style>
  </StackPanel.Resources>
</StackPanel>

이로 인해 Visual Studio 2010은 치명적인 실패 오류로 즉시 종료되었습니다 (hresult : 0x8000ffff (e_unexpected)). https://connect.microsoft.com/visualstudio/feedback/details/753211/xaml-editor-window-fails-with-catastrophic-failure-when-a-style-tries-property#

grid.columnspacing, Grid.RowSpacing, stackpanel.spacing 이제 UWP 미리보기에 있으며 여기에서 요청한 내용을 더 잘 압수 할 수 있습니다.

이 속성은 현재 Windows 10 Fall Creators 업데이트 내부자 SDK에서만 사용할 수 있지만 최종 비트로 만들어야합니다!

UniformGrid는 Silverlight에서 사용할 수 없지만 누군가가 WPF에서 포팅했습니다. http://www.jeff.wilcox.name/2009/01/uniform-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();
        }
    }
}

때로는 기본값보다 더 작게 만들기 위해 마진이 아닌 패딩을 설정해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top