[프로그래밍 언어]/C#

[WPF] 2. 레이아웃 제어

창모의 개발사전 2025. 9. 15. 09:56

 

아래 사이트는 WPF기초부터 단계별로 차근차근 잘 소개가 되어있는 사이트이다. 글은 모두 영어로 되어 있지만

브라우저 번역을 진행해도 부자연스럽지 않게 번역이 되어 WPF를 입문하는 이들에게는 좋은 자료가 될 거라 생각한다.

 

 

지금부터 정리하는 내용은 아래 사이트의 내용을 토대로 작성된다!

https://wpf-tutorial.com/

 

Welcome - The complete WPF tutorial

The complete WPF tutorial Welcome to this WPF tutorial, currently consisting of 126 articles, where you'll learn to make your own applications using the WPF UI framework. If you're brand new to WPF, then we recommend that you start from the first chapter a

wpf-tutorial.com

 

 

[Canvas]

WinForms 방식을 모방한 패널이다.

이 패널 안의 자식 컨트롤들에 좌표를 할당하여 레이아웃을 제어할 수 있다.

절대 좌표를 이용하여 컨트롤하는 것이기 때문에 유연성은 떨어진다.

예를 들어 창의 크기를 키워도 컨트롤들은 절대좌표 자리에 그대로 위치한다.

<Canvas>
    <Button Canvas.Left="10" Canvas.Top="10">버튼 1</Button>
    <Button Canvas.Right="10" Canvas.Top="10">버튼 2</Button>
    <Button Canvas.Bottom="10" Canvas.Left="10">버튼 3</Button>
    <Button Canvas.Bottom="10" Canvas.Right="10">버튼 4</Button>
</Canvas>

 

이러한 형태로 Left, Right, Top, Bottom을 기준으로 각 좌표값을 지정하여 원하는 위치에 배치시킬 수 있다.

이때 해당 위치에 다른 컨트롤이 있는지에 대해서는 신경 쓰지 않고, 그 위치에 다른 컨트롤이 존재하면 그냥 덮어 써버린다.

바로 이게 단점이자 장점이 될 수 있는데 이 장점들을 적극적으로 활용하는 부분이 페인팅 부분이다.

패널의 이름으로도 알 수 있듯이 Canvas. 이런 색상 등 일러스트레이션을 만들 때 유용하다.

<Canvas>
    <Ellipse Fill="Salmon" Canvas.Left="25" Canvas.Top="25" Width="200" Height="200"/>
    <Rectangle Fill="Aqua" Canvas.Left="50" Canvas.Top="50" Width="50" Height="50"/>
    <Rectangle Fill="Yellow" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50"/>
    <Rectangle Fill="Green" Canvas.Left="100" Canvas.Top="100" Width="50" Height="50"/>
</Canvas>

 

기본적으로 이렇게 도형을 그릴 때에는 입력된 코드의 순서대로 그 위에 덮어써진다.

Salmon - Aqua - Yellow - Green 순으로 그려진 걸 볼 수 있다.

 

이것을 좀 더 편한 방법으로 원하는 도형의 우선순위를 지정할 수 있는데, 이때 사용하는 것이 'z-index'이다.

<Canvas>
    <Ellipse Panel.ZIndex="2" Fill="Salmon" Canvas.Left="25" Canvas.Top="25" Width="200" Height="200"/>
    <Rectangle Panel.ZIndex="1" Fill="Aqua" Canvas.Left="40" Canvas.Top="40" Width="50" Height="50"/>
    <Rectangle Panel.ZIndex="4" Fill="Yellow" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50"/>
    <Rectangle Panel.ZIndex="2" Fill="Green" Canvas.Left="100" Canvas.Top="100" Width="50" Height="50"/>
</Canvas>

 

예를 들어 이런 식으로 z-index를 지정해 줬을 때, 도형의 배치는 위처럼 바뀐다.

z-index는 기본값이 0이며 이 인덱스의 값으로 도형의 우선순위를 정할 수 있다.

기본적으로 인덱스의 값이 큰 것이 작은 것보다 우선순위가 높다. (z-index : 3 > z-index : 2) 

만약 두 컨트롤의 인덱스 값이 같다면 그때는 코드의 입력 순으로 배치를 하게 된다.

현재 Ellipse와 Green색 Rectangel의 인덱스 값이 같지만 Rectangle이 마지막에 입력되었기 때문에 Ellipse위에 배치된다.


[WrapPanel]

WrapPanel 안의 자식 컨트롤을 세로 또는 가로로 나란히 배치해 더 이상 공간이 없으면 자동으로 줄 바꿈 하여 배치하는 패널.

바로 예시로 보면,

<WrapPanel>
    <Button Width="150">버튼1</Button>
    <Button Width="150">버튼2</Button>
    <Button Width="150">버튼3</Button>
    <Button Width="150">버튼4</Button>
    <Button Width="150" Height="50">버튼5</Button>
    <Button Width="150">버튼6</Button>
    <Button Width="150">버튼7</Button>
</WrapPanel>

 

Width가 150인 버튼 3개를 입력하고, 화면 길이가 500이기 때문에 그다음 버튼은 자동으로 줄바꿈이 되어 다음 줄에 배치된다.

그 다음 줄에 Height가 50인 버튼5가 배치되어 있기 때문에 해당 줄의 모든 버튼은 버튼5의 Height의 크기에 따른다.

실제 창의 크기를 늘려 버튼5가 첫번째 줄에 배치되도록 하면 자동으로 모든 버튼이 버튼5의 높이에 맞춰진다.

 

반대로 세로 방향으로 컨트롤을 배치하려고 한다면 Orientation옵션을 Veritcal로 설정해주면 되는데

<WrapPanel Orientation="Vertical">
    <Button Width="150" Height="90">버튼1</Button>
    <Button Height="90">버튼2</Button>
    <Button Height="90">버튼3</Button>
    <Button Width="100" Height="90">버튼4</Button>
    <Button Height="90">버튼5</Button>
    <Button Height="90">버튼6</Button>
    <Button Height="90">버튼7</Button>
</WrapPanel>

 

이렇게 아래방향으로 쌓이는 걸 볼 수 있고, 이전 가로방향과는 다르게 세로 방향에서는 해당 줄의 컨트롤 중 가장 Width가 큰 것에

크기를 맞춘다.

다만 높이는 사용자의 설정에 맞게 바뀌고 Width만 바뀐다는 걸 기억하자!

 

* WrapPanel이 가로 방향을 사용하는 경우, 자식 컨트롤들은 가장 높은 항목을 기준으로 동일한 높이가 지정된다.  
  WrapPanel이 세로 방향을 사용하는 경우, 자식 컨트롤들은 가장 넓은 항목을 기준으로 동일한 너비가 지정된다.


[StackPanel]

StackPanel은 WrapPanel과 비슷하지만 한 가지 큰 차이가 존재하는데 

<StackPanel>
    <Button>버튼1</Button>
    <Button>버튼2</Button>
    <Button>버튼3</Button>
    <Button>버튼4</Button>
    <Button>버튼5</Button>
    <Button>버튼6</Button>
    <Button>버튼7</Button>
    <Button>버튼8</Button>
</StackPanel>

 

이미지와 같이 WrapPanel은 줄바꿈이 되어 윈도우 크기 내에서 배치됐지만 StackPanel은 버튼8이 윈도우 크기 상관없이 

배치되는 걸 볼 수 있다.

이게 바로 큰 차이점이고, 또 하나 각 버튼들의 Width가 패널의 크기에 맞게 꽉 차 있다.

 

<StackPanel Orientation="Horizontal">

 

가로로 정렬할 경우도 버튼들의 세로가 늘어난다.

이렇게 각 컨트롤의 Width, Height가 패널의 크기에 맞춰지게 되는데,

HorizontalAlignment, VerticalAlignment 속성들을 통해 자식 컨트롤들을 재정의 가능하다.

 

<StackPanel Orientation="Horizontal">
    <Button VerticalAlignment="Top">버튼1</Button>
    <Button VerticalAlignment="Center">버튼2</Button>
    <Button VerticalAlignment="Bottom">버튼3</Button>
    <Button VerticalAlignment="Top">버튼4</Button>
    <Button VerticalAlignment="Center">버튼5</Button>
    <Button VerticalAlignment="Top">버튼6</Button>
</StackPanel>

 

이런 식의 위치 제어가 가능하다.

즉 컨트롤을 좌표로 제어하지 못하고 그냥 차곡차곡 쌓는 역할만 하는 패널이라고 생각하면 된다.

그렇기 때문에 이런 특징을 잘 활용할 수 있는 부분에 사용하면 되고,

사용 시 각 컨트롤의 크기만큼 공간을 차지하게 되고, 차지하는 공간이 패널보다 커지면 컨텐츠가 잘릴 수도 있다는 걸 명심하자!


 

 

'[프로그래밍 언어] > C#' 카테고리의 다른 글

[WPF] 3. 기본 컨트롤  (0) 2025.11.12
[WPF] 1. 기초 WPF 애플리케이션 생성하기  (3) 2025.08.25