Silverlight를 설치하려면 여기를 클릭합니다.*
Korea 대한민국변경|Microsoft 전체 사이트
MSDN
|개발자 센터
MSDN 홈 > MSDN 칼럼 > Windows Forms > Windows Forms 레이아웃

Windows Forms 레이아웃

Chris Sells
Sells Brothers Consulting  

2002년 12월 5일

요약: Chris Sells는 폼에서 컨트롤의 배율 조정 및 정렬 방법, 입력할 데이터 크기 및 시스템 글꼴 크기와 관련된 다양한 사용자 요구를 충족시키기 위해 배율 및 정렬 기능을 사용하는 방법을 설명합니다(8페이지/인쇄 페이지 기준).

winforms12102002.exe 샘플 파일을 다운로드합니다. 샘플 프로그램 파일에서는 프로그래머의 설명이 영문으로 되어 있으나 이 기사에서는 설명을 돕기 위해 해당 부분을 번역하였습니다.

중요한 스레딩 및 보안 부분을 모두 다룬 다음, Windows Forms의 새로운 기능 중 가장 경쟁력있는 하나를 선택하여 약간의 기본 사항, 즉 폼에서 컨트롤의 배율을 조정하고 정렬하는 방법을 살펴보려고 합니다. 이러한 배율 및 정렬 기능은 입력할 데이터의 크기와 시스템 글꼴 크기에 관한 다양한 사용자 요구를 충족시키는 데 사용됩니다.

폼 크기 자동 조정

예를 들어, 디스플레이 제어판에서 시스템 글꼴 크기를 보통(96dpi)으로 설정하여 폼을 배치할 경우 사용자가 큰 글꼴 설정(120dpi) 또는 사용자 지정 설정 중 하나를 사용하더라도 그림 1과 같은 폼에서 모든 글꼴 크기가 제대로 표시되기를 바랄 것입니다.

그림 1. 보통 크기 글꼴의 예제 폼

디스플레이 제어판에서 보통 글꼴을 큰 글꼴로 변경한 다음, Microsoft Windows XP를 다시 시작하여 실제 테스트를 실행하면 응용 프로그램을 다시 컴파일하지 않아도 새로운 글꼴 크기가 적용된 폼이 그림 2처럼 나타나는 것을 볼 수 있습니다.

그림 2. 큰 글꼴의 예제 폼

이러한 방법의 비밀은 AutoScale이라는 폼 속성입니다. 폼을 처음 로드했을 때 AutoScale이 true(기본값)로 설정되어 있는 경우 폼에서 AutoScaleBaseSize라는 또 다른 속성을 사용합니다. 이 속성은 디자이너에서 설정되며 폼의 글꼴에서 문자의 평균 너비와 높이를 지정합니다. Windows XP의 보통 글꼴에서 기본 글꼴인 8.25pt MS Sans Serif는 평균 너비와 높이가 5x13입니다. 이 정보는 다음과 같이 InitializeComponent 함수로 인코딩됩니다.

this.AutoScaleBaseSize = new Size(5, 13);

큰 글꼴에서 기본 글꼴은 7.8pt MS Sans Serif가 되지만 글꼴의 평균 너비와 높이는 이제 6x15로 커집니다. 그래서 이 글꼴을 "큰" 글꼴이라고 합니다. 로드할 때 폼에서 Form.GetAutoScaleSize를 호출하여 원래 디자인되었던 배율과 현재 배율 간의 차이를 안 다음, 폼과 폼 컨트롤의 높이와 너비를 컨트롤의 위치와 함께 조정합니다. 따라서 시스템 글꼴 설정에 상관없이 폼이 거의 같게 느껴지는 것입니다.

앵커

물론 사용자가 원하는 대로 폼을 조정하는 작업으로 시스템 글꼴 배율 설정만 있는 것은 아닙니다. 예를 들어, 현재 예제의 사용자가 텍스트 상자에 더 긴 문자열을 입력하려는 경우 그림 3처럼 폼을 더 넓히려 할 수도 있습니다.

그림 3. 위쪽, 왼쪽에 앵커된 모든 컨트롤

하지만 폼에 더 많은 공간이 확보되더라도 포함되어 있는 컨트롤에서 더 많은 공간을 차지하지 못한다면 사용자는 만족하지 않을 것입니다. 이상적으로는 다음과 같이 폼이 확장될 때 텍스트 상자도 확장되길 바라게 됩니다.

int delta = 0;

void Form1_Load(object sender, EventArgs e) {
  delta = ClientRectangle.Width - textBox1.Width;
}

void Form1_SizeChanged(object sender, EventArgs e) {
  textBox1.Width = ClientRectangle.Width - delta;
}

폼의 Load 이벤트 중에 텍스트 상자 너비와 클라이언트 사각형 너비 간의 델타를 보관하여 폼의 크기가 변경될 때 텍스트 상자의 너비를 다시 설정하여 너비 차이를 일정하게 유지할 수 있습니다. 이 차이를 일정하게 유지한다는 것은 텍스트 상자의 오른쪽 모서리와 폼의 오른쪽 모서리로부터의 고정 픽셀 수 사이의 차이를 유지한다는 의미입니다. 이것을 앵커라고 합니다. 기본적으로 모든 컨트롤은 다른 컨트롤을 포함하는 폼이나 컨트롤이 될 수 있는 컨테이너의 위쪽과 왼쪽 모서리에 앵커됩니다. 컨테이너의 왼쪽이나 위쪽 모서리가 변경될 때마다 이 앵커를 그대로 유지할 수 있도록 하위 컨트롤을 이동하는 운영 체제에 대해서는 이미 잘 알고 있을 것입니다. 하지만 운영 체제는 그 정도만 할 수 있습니다. 운영 체제는 컨트롤을 다른 모서리에 앵커하여 코드의 크기를 조정하거나 폼 스타일의 크기를 고정하도록 컨트롤의 크기를 조정하지는 않습니다. 다행히도 Windows Forms는 앵커를 직접 지원하므로 이 코드를 우리가 직접 작성할 필요는 없습니다.

다음과 같이 AnchorStyles 열거 값의 조합이 되도록 Anchor 속성을 변경하여 컨트롤이 앵커되는 모서리를 변경할 수 있습니다.

enum AnchorStyles {
  None,
  Left, // 기본값
  Top, // 기본값
  Bottom,
  Right,
}

폼 크기가 조정될 때마다 현재 예제의 텍스트 상자가 조정되도록 크기를 조정하는 것은 왼쪽과 위쪽 모서리와 함께 오른쪽 모서리를 포함하도록 Anchor 속성을 변경하는 것입니다. 속성 브라우저를 사용하면 그림 4와 같은 환상적인 드롭다운 편집기를 사용할 수 있습니다.

그림 4. 속성 브라우저에서 Anchor 속성 설정

도킹

배율과 앵커는 강력하기는 하지만 모든 작업을 할 수 있는 것은 아닙니다. 예를 들어, 텍스트 편집기를 만들려는 경우 메뉴, 도구 모음 및 상태 표시줄이 차지하지 않는 클라이언트 영역의 나머지 부분을 텍스트 상자가 차지하게 하면서 메뉴, 도구 모음 및 상태 표시줄도 함께 표시하려는 경우가 있습니다. 일부 컨트롤의 경우 공간을 직접 찾는 런타임 환경에 따라 필요한 공간이 달라지기 때문에 앵커가 다소 어렵게 됩니다. 모서리에서 0픽셀 떨어진 위치에 앵커하려는 것보다는 폼에서 클라이언트 영역에 남아 있는 공간을 텍스트 상자가 모두 차지하도록 하는 것이 더 쉽습니다. 그래서 도킹을 사용하는 것입니다.

도킹은 컨트롤이 차지할 특정 모서리를 지정하는 방법입니다. 예를 들어, 그림 5에서는 세 개의 컨트롤이 모두 도킹되어 있는 폼을 보여 줍니다. 메뉴는 위쪽 모서리에 도킹되고 상태 표시줄은 아래쪽 모서리에 도킹되고 텍스트 상자는 나머지 부분을 채우도록 도킹되어 있습니다.

그림 5. 도킹 예제

각 컨트롤의 Dock 속성을 그림 6에 나오는 대로 속성 브라우저에 있는 DockStyle 열거 값 중 하나로 설정하여 도킹 동작을 사용할 수 있습니다.

enum DockStyle {
  None, // 기본값
  Left,
  Top,
  Right,
  Bottom,
  Fill,
}

그림 6. 속성 브라우저에서 Dock 속성 설정

분할

도킹을 사용할 때 폼 자체의 크기에 상관없이 사용자가 일부 컨트롤의 크기를 조정할 수 있도록 해야 하는 경우가 많이 있습니다. 예를 들어, Windows 파일 탐색기에서는 도구 모음과 상태 표시줄 사이의 공간을 분할하여 왼쪽에는 폴더 트리를 표시하고 오른쪽에는 해당 목록을 표시합니다. 이러한 컨트롤의 크기를 조정할 수 있도록 파일 탐색기에는 분할자라는 구분 막대가 제공되어 컨트롤 사이에 공유된 공간 비율을 사용자가 끌어서 변경할 수 있도록 합니다. 왼쪽 모서리에 도킹된 TreeView 컨트롤과 채우기 위해 도킹된 ListView 컨트롤 사이의 Splitter 컨트롤에 대한 간단한 예제가 그림 7에 표시됩니다.

그림 7. 분할 예제(끌 수 있음을 나타내는 커서에 유의)

Splitter 컨트롤은 도구 상자에서 사용할 수 있습니다. Dock 속성을 DockStyle.Left(기본값)로 설정하여 컨트롤을 세로로 분할하거나 Dock 속성을 DockStyle.Top으로 설정하여 가로로 분할할 수 있습니다. 가로 분할의 예제는 그림 8에 표시됩니다.

그림 8. 가로 분할

그룹화

고급 레이아웃 효과를 내기 위해 문제를 그룹으로 나눠야 할 경우가 많이 있습니다. 예를 들어, 그림 9에 나오는 것처럼 왼쪽에는 사람들 목록이 오고 오른쪽에는 선택한 사람에 대한 세부 정보가 있다고 가정해 봅시다.

그림 9. 그룹화, 도킹 및 앵커 예제

이 예제에는 이미 알고 있는 개념이 있습니다. 두 개의 그룹 상자 컨트롤을 분할하는 분할자가 가운데에 있습니다. 그림 하나만 보고는 알 수 없지만 그룹 상자 크기가 변경되면 그룹 상자 내의 컨트롤 크기도 변경됩니다. 이것이 가능한 것은 그룹 상자의 두 가지 특성 때문입니다. 첫 번째 특성은 그룹 상자가 폼과 마찬가지로 하위 컨트롤의 상위 역할을 하는 컨테이너 컨트롤이라는 것입니다. 왼쪽의 목록 상자는 폼 자체의 하위 요소가 아니라 왼쪽에 있는 그룹 상자의 하위 요소입니다. 마찬가지로 오른쪽에 있는 레이블과 텍스트 상자 컨트롤은 오른쪽에 있는 그룹 상자의 하위 요소입니다.

컨테이너 컨트롤의 두 번째 중요한 특성은 하위 컨트롤이 앵커되거나 도킹될 수 있도록 폼과 동일한 레이아웃 특징을 공유한다는 것입니다. 이러한 이유로 컨트롤의 앵커 및 도킹 설정은 폼의 모서리에 관련된 것이 아니라 컨테이너 모서리, 즉 이 경우에는 그룹 상자와 관련된 것입니다. 따라서 그림 9의 목록 상자는 그룹 상자의 전체 클라이언트 영역을 차지하기 위해 실제로 DockStyle.Fill로 설정됩니다. 마찬가지로 오른쪽에 있는 텍스트 상자의 앵커 속성은 상위 폼에 따라 그룹 상자 위치가 변경되고 너비가 변경됨에 따라 위쪽, 왼쪽 및 오른쪽에 앵커됩니다. 그리고 텍스트 상자는 그룹 상자와 관련하여 예상한 대로 작동합니다.

GroupBox 컨트롤은 Windows Forms에서 제공하는 세 가지 컨테이너 컨트롤 중 하나입니다. 다른 두 가지는 Panel 컨트롤과 TabControl입니다. Panel 컨트롤은 레이블과 프레임이 없다는 것만 제외하면 그룹 상자와 아주 유사합니다. 하위 폼(폼 안에 있는 폼) 같은 모양과 기능을 선호한다면 패널이 더 편리합니다. TabControl은 컨테이너이거나 하나 이상의 TabPage 컨트롤로, 각 컨트롤은 그림 10에 표시된 대로 위쪽에 탭이 있는 컨테이너 컨트롤입니다.

그림 10. 두 개의 TabPage 컨트롤이 있는 TabControl

사용자 지정 레이아웃

앵커, 도킹, 분할 및 그룹화를 조합하면 대부분의 일반 레이아웃 문제를 해결할 수 있습니다. 하지만 모든 문제가 해결되는 것은 아닙니다. 예를 들어, 이러한 기술을 사용하더라도 그림 11에 표시된 대로 테이블이나 표 형식으로 클라이언트 영역 전반에 컨트롤을 자동으로 균등하게 분배하는 것은 불가능합니다.

그림 11. 사용자 지정 레이아웃 예제

그림 11에 표시된 대로 레이아웃을 만들려면 제공된 방법을 최대한 많이 사용한 다음, 나머지 부분을 처리하기 위해 폼이나 컨테이너 컨트롤에서 Layout 이벤트를 사용하는 것이 가장 좋습니다. 예를 들어, 다음 Layout 이벤트 처리기는 폼의 크기가 조정되면 아홉 개의 단추 컨트롤을 비율에 맞게 정렬합니다.

void GridForm_Layout(object sender, LayoutEventArgs e) {
  // 폼의 모눈에 단추를 정렬합니다.
  Button[] buttons = new Button[] { button1, button2, ..., };
  int cx = ClientRectangle.Width/3;
  int cy = ClientRectangle.Height/3;
  for( int row = 0; row != 3; ++row ) {
    for( int col = 0; col != 3; ++col ) {
      Button button = buttons[col * 3 + row];
      button.SetBounds(cx * row, cy * col, cx, cy);
    }
  }
}

정리

배율을 사용하면 디자인 타임에 한 개의 글꼴 설정을 사용하여 폼에 컨트롤을 배열할 수 있으며 다른 글꼴 설정을 사용해도 폼이 올바르게 표시되도록 할 수 있습니다. 예를 들어, 디자인 타임에 컨트롤을 보통 글꼴로 설정했지만 큰 글꼴 설정을 사용하더라도 폼은 여전히 올바르게 표시됩니다. 앵커를 사용하면 특정 모서리에 따라 고정 거리를 유지하는 데 필요한 컨트롤을 이동하고 크기를 조정할 수 있습니다. 도킹을 사용하면 전체 모서리를 컨트롤로 넘겨줄 수 있습니다. 분할을 사용하면 도킹된 컨트롤의 크기를 조정할 수 있습니다. 그룹화를 사용하면 컨트롤 레이아웃을 관리 가능한 부분으로 나눌 수 있습니다. 위 내용 중 제대로 작동하는 것이 없을 경우 Layout 이벤트가 기존 방법으로는 불가능한 것을 가능하게 해 주는 백도어가 됩니다.

참고   이 자료는 Chris Sells가 집필한 Addison-Wesley 표제 Programming Windows Forms Applications with C#(0321116208)에서 발췌한 것입니다. 여기에 소개한 자료는 발행될 책에 나올 내용의 초안입니다.

Chris Sells는 DevelopMentor의 강사이면서 독립 컨설턴트로서 .NET과 COM을 사용한 분산 응용 프로그램 전문가입니다. ATL7용으로 업데이트 중인 ATL Internals를 비롯한 여러 권의 책을 집필했습니다. 그리고 Addison-Wesley의 Essential Windows Forms와 O'Reilly의 Mastering Visual Studio .NET을 진행하고 있습니다. 여가 시간에는 Web Service DevCon을 호스팅하고 Genghis 소스 사용 가능 프로젝트를 감독합니다. Chris와 그의 여러 프로젝트에 대한 자세한 내용을 보려면 http://www.sellsbrothers.com  을 방문하십시오.



최종 수정일: 2003년 2월 24일
Top of Page Top of Page


Microsoft