Layout

WPF의 레이아웃은 패널의 자식 컬렉션에 포함되는 요소들(단추, 텍스트 상자등)을 어떻게 정렬하고 배치 할것인지 지정한다.

레이아웃에 들어가기 전에 WPF에서 리소스를 추가하는 방법에 대해 알아본다.

리소스 추가

솔루션 탐색기에서 Resources.resx 더블 클릭

리소스 추가 다운 버튼 클릭

기존 파일 추가

파일을 추가하면 Resources 폴더가 생기고 추가 된 파일이 Resources 폴더로 복사 된다.
솔루션 탐색기에도 Resources 항목이 자동으로 생성된다.

파일을 추가 할 때 같은 프로젝트 폴더에 있으면 Resources 폴더가 생성되지 않고 파일도 복사하지 않는다.

다음은 솔루션 탐색기에 리소스가 추가된 화면이다.

Image 컨트롤 추가 리소스에 추가하지 않고 바로 추가해도 상관없다.
같은 프로젝트 내에 추가 되면 솔루션 탐색기에 (이전에 추가된 폴더 항목이 없다면)폴더와 파일이 추가 된다.
다른 프로젝트의 폴더라면 Image 폴더가 자동으로 생성 된 후 이미지 파일이 복사 된다.

이제 레이아웃에 대해서 알아보자.
종류별로 설명하겠다.

Canvas :

상대적인 좌표를 사용하여 자식 요소를 명시적으로 배치 할 수 있다.

Canvas는 윈도우를 줄여도 패널안의 요소의 크기나 위치가 변하지 않는다.

 

Canvas
<Window x:Class="Layout.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">
    <Canvas Name="canvas1">
        <Image Canvas.Left="29" Canvas.Top="52" Height="228" Name="image1" Stretch="Fill" Width="342" Source="file:///D:/workWPF/Layout/Resources/Tang_wei.jpg" />
        <Button Canvas.Left="29" Canvas.Top="17" Content="Button1" Height="23" Name="button1" Width="149" />
        <Button Canvas.Left="184" Canvas.Top="17" Content="Button2" Height="23" Name="button2" Width="187" />
    </Canvas>
</Window>

StackPanel  :

수평 또는 세로로 요소들을 배치한다.

스팩의 방향이 수평이면 Orientation="Horizontal" 수직이면 Orientation="Vertical"로 설정한다.
먼저 배치된 요소가 위나 왼쪽에 배치된다.

StackPanel
<Window x:Class="Layout.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 Name="StackPanel" Orientation="Vertical">
        <Image Canvas.Left="29" Canvas.Top="52" Height="228" Name="image1" Stretch="Fill" Width="342" Source="file:///D:/workWPF/Layout/Resources/Tang_wei.jpg" />
        <Button Canvas.Left="29" Canvas.Top="17" Content="Button1" Height="23" Name="button1" Width="149" />
        <Button Canvas.Left="184" Canvas.Top="17" Content="Button2" Height="23" Name="button2" Width="187" />
    </StackPanel>
</Window>

 

WrapPanel :

자식요소들의 크기보다 WrapPanel 사이즈가 작으면 수평으로 배치, 자식의 요소보다 WrapPanel 사이즈가 작으면 스택패널처럼 아래로 내려간다.
문서를 작성할 때 라인을 넘어가면 다음 라인으로 넘어가는것과 같다.

WrapPanel
<Window x:Class="Layout.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">
    <WrapPanel Name="WrapPanel">
        <Image Canvas.Left="29" Canvas.Top="52" Height="228" Name="image1" Stretch="Fill" Width="342" Source="file:///D:/workWPF/Layout/Resources/Tang_wei.jpg" />
        <Button Canvas.Left="29" Canvas.Top="17" Content="Button1" Height="23" Name="button1" Width="149" />
        <Button Canvas.Left="184" Canvas.Top="17" Content="Button2" Height="23" Name="button2" Width="187" />
    </WrapPanel>
</Window>

 

DockPanel :

자식 요소를 Top, Left, Bottom, Right 옵션에 따라 배치를 바꿀수 있다.

 

DockPanel
<Window x:Class="Layout.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">
    <DockPanel Name="DockPanel" LastChildFill="True">
        <Button Content="Button1" Height="23" Name="button1" Width="75" IsCancel="True" DockPanel.Dock="Top" />
        <Button Content="Button2" Height="23" Name="button2" Width="75" />
        <Button Content="Button3" Height="23" Name="button3" Width="75" DockPanel.Dock="Bottom" />
        <Button Content="Button4" Height="30" Name="button4" Width="90" DockPanel.Dock="Right" />
        <Button Content="Button5" Height="23" Name="button5" Width="75" DockPanel.Dock="Top" />
    </DockPanel >
</Window>

Button5는 Top인데도 중간에 위치하고 있다. 마지막 자식 요소는 할당되지 않는 영역을 채울려고 하기 때문에 원하는 위치로 배치가 안된다.

LastChildFill을 옵션을 끄면 남은 역력을 채우지 않기 때문에 원하는 위치로 이동 시킬수 있다.

 

Grid :

ColumnDefinition와 RowDefinition를 사용하여 Grid를 나눌 수 있다.
행과 열에 의해 자식 요소를 배치 할 수 있다.

리소스 에디터에서 ColumnDefinition와 RowDefinition를 정의한 모습이다.

Grid
<Window x:Class="Layout.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">
    <Grid Name="grid1" Width="400">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Button Content="Button1" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"/>
        <Button Content="Button2" Grid.Column="2" Grid.RowSpan="3"/>
    </Grid>
</Window>