StackPanel의 아이들이 최대 공간을 아래쪽으로 채우도록하는 방법은 무엇입니까?


356

왼쪽에 텍스트를 보내고 오른쪽에 도움말 상자를 원합니다.

도움말 상자가 맨 아래까지 뻗어 있어야합니다.

StackPanel아래 바깥 쪽을 꺼내면 잘 작동합니다.

그러나 레이아웃 때문에 (UserControls를 동적으로 삽입하고 있습니다) 래핑이 필요합니다 StackPanel.

내가 시도한 것을 볼 수 있듯이 GroupBox의 아래쪽으로 확장 하는 방법은 무엇입니까?StackPanel

  • VerticalAlignment="Stretch"
  • VerticalContentAlignment="Stretch"
  • Height="Auto"

XAML :

<Window x:Class="TestDynamic033.Test3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test3" Height="300" Width="600">
    <StackPanel 
        VerticalAlignment="Stretch" 
        Height="Auto">

        <DockPanel 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            Height="Auto" 
            Margin="10">

            <GroupBox 
                DockPanel.Dock="Right" 
                Header="Help" 
                Width="100" 
                Background="Beige" 
                VerticalAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                Height="Auto">
                <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" />
            </GroupBox>

            <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
                <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
            </StackPanel>

        </DockPanel>
    </StackPanel>
</Window>

대답:

고마워 마크, 그것을 DockPanel대신 사용하여 사용 StackPanel합니다. 일반적으로 DockPanelWPF 레이아웃에 점점 더 많이 사용 하고 있습니다. 고정 XAML은 다음과 같습니다.

<Window x:Class="TestDynamic033.Test3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test3" Height="300" Width="600" MinWidth="500" MinHeight="200">
    <DockPanel 
        VerticalAlignment="Stretch" 
        Height="Auto">

        <DockPanel 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            Height="Auto" 
            MinWidth="400"
            Margin="10">

            <GroupBox 
                DockPanel.Dock="Right" 
                Header="Help" 
                Width="100" 
                VerticalAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                Height="Auto">
                <Border CornerRadius="3" Background="Beige">
                    <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" 

                Padding="5"/>
                </Border>
            </GroupBox>

            <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
                <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
            </StackPanel>

        </DockPanel>
    </DockPanel>
</Window>

서식을 수정했습니다. 목록에서 코드로 바로가는 것을 좋아하지 않습니다
Greg

1
GroupBox를 자체적으로 확장 할 수 있습니까? 그렇다면 레이아웃을 어기는 요소를 찾을 때까지 부모 요소를 하나씩 추가하십시오.
Drew Noakes

RoBorg : 감사합니다
Edward Tanguay

1
감사. 귀하의 답변을 사용하여 2 개의 중첩 DockPanel을 사용하여 매우 비슷한 문제를 해결할 수있었습니다!
Yablargo

답변:


344

StackPanel최종 요소가 나머지 공간을 모두 사용 하는 곳 처럼 들립니다 . 그러나 왜 DockPanel? DockPanelwith 의 다른 요소를 장식하면 DockPanel.Dock="Top"도움말 컨트롤이 나머지 공간을 채울 수 있습니다.

XAML :

<DockPanel Width="200" Height="200" Background="PowderBlue">
    <TextBlock DockPanel.Dock="Top">Something</TextBlock>
    <TextBlock DockPanel.Dock="Top">Something else</TextBlock>
    <DockPanel
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Height="Auto" 
        Margin="10">

      <GroupBox 
        DockPanel.Dock="Right" 
        Header="Help" 
        Width="100" 
        Background="Beige" 
        VerticalAlignment="Stretch" 
        VerticalContentAlignment="Stretch" 
        Height="Auto">
        <TextBlock Text="This is the help that is available on the news screen." 
                   TextWrapping="Wrap" />
     </GroupBox>

      <StackPanel DockPanel.Dock="Left" Margin="10" 
           Width="Auto" HorizontalAlignment="Stretch">
          <TextBlock Text="Here is the news that should wrap around." 
                     TextWrapping="Wrap"/>
      </StackPanel>
    </DockPanel>
</DockPanel>

DockPanel사용 가능한 플랫폼이없는 플랫폼 (예 : WindowsStore) 인 경우 그리드를 사용하여 동일한 효과를 만들 수 있습니다. 대신 그리드를 사용하여 수행 한 위의 예는 다음과 같습니다.

<Grid Width="200" Height="200" Background="PowderBlue">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0">
        <TextBlock>Something</TextBlock>
        <TextBlock>Something else</TextBlock>
    </StackPanel>
    <Grid Height="Auto" Grid.Row="1" Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <GroupBox
            Width="100"
            Height="Auto"
            Grid.Column="1"
            Background="Beige"
            Header="Help">
            <TextBlock Text="This is the help that is available on the news screen." 
              TextWrapping="Wrap"/>
        </GroupBox>
        <StackPanel Width="Auto" Margin="10" DockPanel.Dock="Left">
            <TextBlock Text="Here is the news that should wrap around." 
              TextWrapping="Wrap"/>
        </StackPanel>
    </Grid>
</Grid>

18
훌륭한! 지난 한 시간 동안 StackPanel 이이 작업을 수행하는 방법을 알아 내려고 노력했습니다. 이제부터는 먼저 WPF (및 기타) 정보를 찾아 보겠습니다.
paxdiablo 2016 년

7
StackPanels가 원하는 작업을 수행하는 데 얼마나 많은 시간을 소비했는지 믿을 수 없습니다. 공유해 주셔서 감사합니다! DockPanels는 내가 원했던 것입니다.
danglund

태블릿 용 도크 패널은 없습니다. telerik.com/forums/following-blog-post-and-comparison
JP Hellemons

1
Windows 스토어 앱용 독 패널이 없습니다.
Teoman shipahi

이제는 범용 앱에 관한 것이지만 범용 앱은 아직 DockPanel을 지원하지 않습니까?
yonexbat

105

이런 일이 발생하는 이유는 스택 패널이 요소를 쌓을 축에 대한 제약 조건으로 양의 무한대를 가진 모든 자식 요소를 측정하기 때문입니다. 자식 컨트롤은 원하는 크기를 반환해야합니다 (양의 무한대는 어느 축의 MeasureOverride 에서 유효한 반환 값이 아님 ). 따라서 모든 것이 들어갈 수있는 가장 작은 크기를 반환합니다. 그들은 실제로 얼마나 많은 공간을 채워야하는지 알 방법이 없습니다.

뷰에 스크롤 기능이 필요하지 않고 위의 답변이 필요에 맞지 않으면 자신의 패널을 구현하는 것이 좋습니다. 아마도 StackPanel에서 직접 파생 될 수 있으며 ArrangeOverride 메소드를 변경 하여 나머지 요소를 하위 요소간에 나눕니다 (각각 동일한 양의 추가 공간 제공). 원하는 것보다 더 많은 공간이 주어지면 요소가 제대로 렌더링되어야하지만, 더 적게 주면 글리치를 볼 수 있습니다.

전체를 스크롤 할 수 있기를 원한다면 ScrollViewer가 작업 할 수있는 무한한 공간을 제공하므로 하위 요소와 동일한 위치에 배치 할 수 있기 때문에 일이 조금 더 어려울 것입니다. 원래. 이 상황에서 새 패널에 뷰포트 크기를 지정할 수있는 새 속성을 만들려면이 속성을 ScrollViewer의 크기에 바인딩 할 수 있어야합니다. 이상적으로는 IScrollInfo를 구현 하지만 모든 것을 올바르게 구현하면 복잡해지기 시작합니다.


+1, 나는 당신에게 더 많이 줄 것이지만 1은 허용됩니다. 첫 번째 단락은 수많은 Microsoft 페이지가 실패한 것을 지적했습니다. .
Aidan

그리드 내부의 StackPanel은 그의 일반적인 요구를 매우 쉽게 해결합니다. 필요한 경우 맨 아래 비트를 ScrollViewer에 넣을 수 있습니다. 저는 2006 년부터 WPF를 해왔으며 사용자 지정 패널을 한 번만 수행하면됩니다. 추가 복잡성을 권장하는 것은 좋은 생각이 아닙니다.
Chris Bordeman

@ChrisBordeman 그리드 내부의 스택 패널이 문제를 어떻게 해결하는지 잘 모르겠습니다. 사용 가능한 공간을 채우기 위해 스택 패널에 하나 이상의 자식 요소를 늘려야합니다. 스택 패널을 그리드 안에 넣는다 고해서 그렇게하지 않습니까?
Caleb Vear

61

다른 방법은 하나의 열과 n 개의 행이 있는 Grid를 사용하는 것 입니다. 모든 행 높이를로 설정 Auto하고 맨 아래 행 높이를로 설정하십시오 1*.

그리드가 DockPanels, StackPanels 및 WrapPanels보다 레이아웃 성능이 우수하다는 것을 알았 기 때문에이 방법을 선호합니다. 그러나 많은 수의 항목에 대해 레이아웃이 수행되는 ItemTemplate에서 사용하지 않으면 아마 눈치 채지 못할 것입니다.


1
나를 위해 최고의 솔루션입니다. 이것으로 하나 이상의 성장하는 행을 정의 할 수 있습니다
niyou

18

SpicyTaco.AutoGrid- 의 수정 된 버전을 사용할 수 있습니다 StackPanel.

<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10">
   <Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/>
   <Button Content="Cancel"/>
   <Button Content="Save"/>
</st:StackPanel>

첫 번째 버튼이 채워집니다.

NuGet을 통해 설치할 수 있습니다.

Install-Package SpicyTaco.AutoGrid

SpicyTaco.AutoGrid를 살펴 보는 것이 좋습니다 . 그것은 대신 WPF의 형태에 매우 유용합니다 DockPanel, StackPanel그리고 Grid매우 쉽고 우아하게 스트레칭으로 문제를 해결한다. GitHub의 readme를 살펴보십시오.

<st:AutoGrid Columns="160,*" ChildMargin="3">
    <Label Content="Name:"/>
    <TextBox/>

    <Label Content="E-Mail:"/>
    <TextBox/>

    <Label Content="Comment:"/>
    <TextBox/>
</st:AutoGrid>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.