MSDN : http://msdn2.microsoft.com/en-us/library/ms748948.aspx

WPF Windows Overview

사용자는 WPF 독립 애플리케이션과 주로 시각화한 데이터 컨텐트를 보여주고 사용자를 데이터와 상호작용 할 수 있도록 하는 윈도를 통하여 상호작용 합니다.

이 토픽은 다음 섹션을 담고 있습니다.

Window 클래스

다음 그림은 일반적인 윈도의 요소를 나타냅니다.

사용자 삽입 이미지

윈도는 비클라이언트 영역과 클라이언트 영역의 두 영영으로 나뉩니다.

윈도의 비클라이언트 영역은 WPF에 의해 구현되고, 대부분의 윈도에게 공통적인 다음과 같은 요소를 포함합니다.

  • 테두리(border)
  • 타이틀 바
  • 아이콘
  • 최소화, 최대화 및 원래 크기로 버튼
  • 닫기 버튼
  • 최소화, 최대화, 원래 크기로, 이동, 크기 조정 및 닫기를 위한 메뉴 아이템을 제공하는 시스템 메뉴

윈도의 클라이언트 영역은 윈도의 비클라이언트 영역 내의 영역이고, 윈도-정의(window-specific)내용을 표현하기 위해 개발자가 사용합니다.

WPF에서, 윈도는 다음과 같은 것을 가능케하는 Window 클래스에 의해 캡슐화됩니다.

  • 윈도의 크기, 위치 및 형태를 설정.
  • 윈도 내에 내용을 얹음.
  • 윈도를 보여줌.
  • 윈도의 라이프타임을 관리

메시지 박스와 다이얼로그 박스는 윈도의 다른 형식이며 Dialog Boxex Overview에서 다룹니다. 또한, NavigationWindowWindow에서 상속된 윈도의 특별한 형식이며 컨텐트를 표시하고 운항(네비게이션)하기 위한 지원을 확장합니다(Navigation Overview를 참고합니다).

윈도 구현

윈도의 구현은 형태(appearance)와 동작(behavior)을 포괄합니다. 형태는 윈도를 보여주는 방법이며, 동작은 윈도가 작용하는 방법입니다. WPF에서, 코드나 마크업 혹은 둘 다를 사용하여 윈도의 형태와 동작을 구현할 수 있습니다. 그러나, 마크업과 코드-비하인드가 -둘을 모두 사용하는 것이- 가장 일반적입니다.

마크업과 코드-비하인드에서 윈도를 정의하기
마크업과 코드-비하인드를 모두 사용하여 윈도를 구현하는 것은, 형태를 정의하기 위해 XAML의 풍부한 표현을 활용할 수 있고, 동작을 구현하기 위해 코드를 사용하는 것과 같이 둘 모두를 위해 가장 좋습니다.

다음 예제는 마크업과 코드를 모두 사용하여 구현된 윈도를 보여줍니다.
(※역주 : 원문에는 모두 XAML 코드로 나와있지만 내용상 XAML과 C#으로 구분하였습니다.)

XAML
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="MarkupAndCodeBehindWindow">
  <!-- Client Area (for content) -->
</Window>
C#

using System.Windows;

public partial class MarkupAndCodeBehindWindow : Window

{

    public MarkupAndCodeBehindWindow()

    {

        InitializeComponent();

    }

}

마크업 파일과 코드-비하인드 파일이 함께 동작하게 하기 위해서 다음과 같은 사항이 요구됩니다.

  • 마크업에서, Window 엘리먼트는 x:Class 어트리뷰트에 의해 지정된 이름을 가진 프로젝트가 빌드될 때 마크업 파일을 위한 partial class를 생성하도록 MSBuild에게 지시하는 x:Class 어트리뷰트를 포함해야 합니다. 이것은 XAML 스키마(xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml")를 위한 추가적인 XML 네임스페이스 선언을 필요로 합니다. 부분적으로 생성된 partial class는 이벤트를 등록하고 마크업에 의해 구현된 프로퍼티를 설정하기 위해 호출되는 InitializeComponent를 구현합니다.
  • 코드-비하인드에서, 클래스는 반드시 마크업의 x:Class 어트리뷰트에 의해 지정된 것과 같은 이름을 가진 partial class이어야 하고, Window를 상속할 필요가 있습니다. 이것은 코드-비하인드 파일이 빌드될 때 마크업 파일을 위해 생성된 partial class와 연결되도록 합니다(Building a WPF Application을 참고).
  • 코드-비하인드에서, 클래스는 반드시 InitializeComponent 메소드를 호출하는 생성자를 구현해야 하며 그렇지 않을 경우, 마크업은 적용되지 않을 것입니다.
노트:
Microsoft Visual Studio를 사용하여 프로젝트에 새 윈도를 추가할 때, 윈도는 마크업과 코드-비하인드를 모두 사용하여 구현되고, 마크업과 코드-비하인드 파일 사이의 연결을 생성하는데 필요한 설정을 포함합니다.

다음 예제는 어떻게 윈도 타이틀 설정, XAML을 사용한 버튼 선언 및 코드-비하인드에서 Click 이벤트를 처리하기 위해 마크업과 코드-비하인드를 사용하는지를 보여줍니다.
(※역주 : 역시 XAML과 C#으로 나눕니다.)

XAML
<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MarkupAndCodeBehindWindow"
  Title="WindowsOverviewSnippetsCSharp"
  Height="800"
  Width="600">
    <!-- Client Area (for content) -->
    <Button Click="button_Click">Window Content</Button>
</Window>
C#

using System.Windows;

public partial class MarkupAndCodeBehindWindow : Window

{

    public MarkupAndCodeBehindWindow()

    {

        InitializeComponent();

    }


    void button_Click(object sender, RoutedEventArgs e)

    {

        MessageBox.Show("Button was clicked.");

    }

}

MSBuild를 위한 윈도 정의 설정하기

윈도를 어떻게 정의하느냐에 따라 Microsoft build engine(MSBuild)를 위해 어떻게 설정되었는지를 결정합니다. 마크업과 코드-비하인드 모두를 사용하여 정의된 윈도의 경우,

  • 마크업 파일은 MSBuild Page 아이템으로 설정되어야 합니다.
  • 코드-비하인드 파일은 MSBuild Compie 아이템으로 설정해야 합니다.

이것은 다음 예제와 같이 표시할 수 있습니다.
(※역주 : 다음 코드는 Visual Studio의 프로젝트 파일(.csproj 또는 .vbproj)를 텍스트 편집기로 열여보면 확인할 수 있고, 물론 IDE를 사용하는 경우 이 코드를 직접 수정할 필요가 없습니다. 또한 원문에서의 Include 속성에 들어간 공백은 오타로 생각되어 제거 하였습니다.)

<Project
    DefaultTargets="Build"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    ...
    <Page Include="MarkupAndCodeBehindWindow.xaml" />
    <Compile Include="MarkupAndCodeBehindWindow.xaml.cs" />
    ...
</Project>

여기에서, 코드-비하인드 파일은 MSBuild Compile 아이템으로 설정되었습니다. 또한, 코드-비하인드 파일은 마크업 파일의 이름에 추가적인 언어 구분 접미어(.cs 또는 .vb)가 붙은 것과 같은 이름을 갖습니다. 이 접미어는 마이크로소프트 비주얼 스튜디오가 기본적으로 이런 규칙을 사용하긴 하지만 반드시 필요하진 않습니다.

노트:
WPF 애플리케이션 빌드하기의 더 자세한 내용은 Building a WPF Application을 참고합니다.

윈도 라이프타임

한 번 윈도가 MSBuild를 위해 정의되고 설정되면, 애플리케이션에서 그것을 보여줄 수 있습니다. 어떤 클래스에서도, 윈도는 최초로 인스턴스화 되었을 때 시작되어, 그것이 보이게 된 후 활성화되며 최종적으로 닫히기 전에 비활성화되는 라이프타임을 가집니다.

윈도 열기
윈도를 열기 위해, 다음 예제와 같이 먼저 그것의 인스턴스를 생성해야 합니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    Startup="app_Startup">
</Application>
C#

using System.Windows;

public partial class App : Application

{

    void app_Startup(object sender, StartupEventArgs e)

    {

        // Create a window

        MarkupAndCodeBehindWindow window = new MarkupAndCodeBehindWindow();


        // Open a window

        window.Show();

    }

}

이 예제에서, MarkupAndCodeBehindWindow는 애플리케이션이 시작될 때 인스턴스화 됩니다(Application Management Overview를 참고).

윈도가 인스턴스화 될 때, 그것의 참조가 Application 객체에 의해 관리되는 윈도의 목록(System.Windows.Application.Windows 참고)에 자동적으로 추가됩니다. 또한, 첫 윈도가 인스턴스화 될 때, Application에 의해 기본값으로 메인 애플리케이션 윈도로 설정됩니다(System.Windows.Application 참고).

윈도는 Show 메소드를 호출함으로서 다음 그림이 보여주는 것 처럼 마침내 열립니다.

사용자 삽입 이미지

Show 호출에 의해 열린 윈도는 모덜리스 윈도이며, 이것은 애플리케이션이 사용자가 같은 애플리케이션 내의 다른 윈도를 활성화 할 수 있도록 허용하는 모드로 동작한다는 것을 의미합니다. Window는 또한 모덜 윈도로 열기위해 사용되는 ShowDialog 메소드를 구현합니다. 대부분의 모덜 윈도의 일반적 형식은 Dialog Boxes Overview에서 자세히 다루는 다이얼로그 박스입니다.

더 간단하게, 윈도 구현이 마크업을 포함하는 한, 마크업의 StartupUri 속성을 설정하여 메인 윈도를 자동적으로 열 수 있도록 애플리케이션 정의를 선언적으로 설정할 수 있습니다.

XAML
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="App"
    StartupUri="MarkupAndCodeBehindWindow.xaml">
</Application>

애플리케이션이 시작할 때, 이 마크업은 MarkupAndCodeBehindWindow 윈도가 Show 메소드 호출에 의해 모덜리스로 열리도록 합니다.

Show가 호출되었을 때, 윈도는 그것이 실제로 보이기 전에 처리할 어떤 초기화 작업이 필요합니다. 초기화의 초점은 사용자 입력을 받도록 할 기반의 구성에 맞춰져 있습니다. 초기화가 완료되었을 때, SourceInitialized 이벤트가 발생되고 윈도가 보이게 됩니다.

윈도 소유권
윈도가 Show 호출로 열렸을 때, 그것과 관계가 있는, 또는 그것을 생성한 윈도에 대한 어떠한 정보도 가지고 있지 않습니다. 사용자는 다른 것들과 독립적으로 각 윈도와 상호작용 할 수 있을 것입니다. 이것은 윈도가 다음과 같이 할 수 있다는 것을 의미합니다.

  • 다른 윈도를 가리기(true로 설정된 Topmost 속성을 가진 윈도가 없다면).
  • 다른 윈도에 영향을 주지 않고 최소화, 최대화 및 원래 크기로 돌아가기.

어떤 애플리케이션을 위해, 열려있는 윈도는 그것을 열었던 윈도와 밀접한 관계를 가질 필요가 있습니다. 예를 들어, 통합 개발 환경(IDE) 애플리케이션은 항상 다른 윈도를 생성하거나, 닫거나, 최소화 하거나, 최대화 하거나, 복구하기 위해서 그들의 위에 있어야 할 속성이나 툴 윈도와 같은 윈도를 열 것입니다.

Owner 속성을 설정하여 준비되는 한 윈도가 다른 윈도를 소유(own)하는 관계를 만들어 이러한 동작을 구현할 수 있습니다.

C#
using System.Windows;
public partial class OwnerWindow : System.Windows.Window
{
    public OwnerWindow()
    {
        InitializeComponent();
    }

    void OpenOwnedWindow()
    {
        // NOTE: 소유자는 다른 윈도를 소유하기 전에 반드시 보여야 합니다.
        // Create new owned window and show it
        OwnedWindow ownedWindow = new OwnedWindow();
        ownedWindow.Owner = this;
        ownedWindow.Show();
    }
}

한번 소유권이 만들어지면, 소유된 윈도는 Owner 속성을 통해 자신을 소유한 윈도를 참조할 수 있습니다. 소유 윈도는 OwnedWindows 속성을 나열하여 그것이 소유하고 있는 모든 윈도를 알 수 있습니다.

윈도 활성화
윈도가 처음으로 열렸을 때, 키 눌림과 마우스 클릭과 같은 현재 사용자의 입력을 포착하는 것을 의미하는 포그라운드 윈도(foreground window)가 되며, 이 윈도는 활성 윈도(active window)라고도 합니다. 윈도는 처음으로 열렸거나, 사용자가 선택하였을 때 활성 윈도가 됩니다. 이 모든 경우, 윈도는 Activated 이벤트를 띄웁니다.

노트:
윈도가 처음으로 열렸을 때, Activated 이벤트가 발생된 후 LoadedContentRendered 이벤트가 발생합니다. 따라서, 윈도는 ContentRendered가 발생하였을 때만 열려야 할지를 고려해야 합니다.

윈도가 활성화 된 후, 사용자는 같은 애플리케이션 내의 또 다른 윈도를 활성화 하거나 다른 애플리케이션을 활성화 할 수 있습니다. 그랬을 때, 현재 활성 윈도는 비활성화 되고 Deactivated 이벤트를 띄웁니다.

ActivatedDeactivated를 처리하는 한 가지 이유는 예를 들어, 게임이나 비디오 플레이어와 같이 끊임 없는 사용자의 입력이나 집중이 필요한 윈도가 활성화 되었을 때에만 동작할 수 있는 기능을 사용 가능 또는 사용 불가능하게 하기 위해서 입니다.

다음 예제는 이 동작을 구현하기 위해 어떻게 ActivatedDeactivated를 처리하는지 보여줍니다.

XAML
<Window
    x:Class="CustomMediaPlayerWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Custom Media Player"
    Activated="window_Activated"
    Deactivated="window_Deactivated">
  ...
</Window>
C#

using System.Windows;

public partial class CustomMediaPlayerWindow : Window

{

    ...

    bool isMediaElementPlaying;

    void window_Activated(object sender, EventArgs e)

    {

        // 윈도가 활성화 되면 미디어 재생을 재개

        If (this.isMediaElementPlaying) this.mediaElement.Play();

    }

    void window_Deactivated(object sender, EventArgs e)

    {

        // 미디어가 재생 중이고 윈도가 비활성화 되면 재생을 일시 중지

        if (this.isMediaElementPlaying) this.mediaElement.Pause();

    }

}

노트:
완전한 샘플은 Window Activation and Deactivation Sample을 참고합니다.

때로, 윈도는 활성 윈도가 아닐지라도 코드를 계속 실행해야 할지도 모릅니다. 예를 들어, 메일 클라이언트는 사용자가 다른 애플리케이션을 사용하는 동안 메일 서버를 지속적으로 폴링할 것입니다. 이와 같은 애플리케이션은 종종 메인 윈도가 비활성화 되었을 때 다른, 혹은 추가적인 동작을 제공합니다. 메일 프로그램의 경우를 고려해봤을 때, 이것은 새 메일을 받은 편지함에 추가하는 것 뿐만 아니라, 사용자에게 통지하기 위한 시스템 트레이에 아이콘을 추가하는 것도 의미합니다. 애플리케이션이 이런 동작을 수행할 필요가 있는지를 결정하기 위해, IsActive 속성을 검사하여 윈도가 활성화 되었는지 아닌지를 검출할 수 있습니다.

다른 경우, 윈도는 특별히 더 긴급하게 사용자에게 통지를 할 필요가 있다면, 활성 윈도가 되길 원할 것입니다. 이것은 Activate 메소드를 호출하여 가능합니다.

노트 :
System.Windows.Application.ActivatedSystem.Windows.Application.Deactivated 이벤트를 사용하여 애플리케이션-스코프 활성화를 처리할 수 있습니다.

윈도 닫기
사용자가 윈도 사용을 마쳤을 때, 그것을 닫길 바랄 것입니다. 윈도는 다음과 같은 비클라이언트 영역의 요소를 사용하여 닫을 수 있습니다.

  • System 메뉴의 Close 아이템.
  • ALT+F4를 누름.
  • Close 버튼을 누름.

개발자는 윈도를 닫기 위해 다음과 같이 클라이언트 영역에 커스텀 메커니즘을 추가할 수도 있습니다.

  • 일반적으로 메인 애플리케이션을 위한 File 메뉴에 있는 Exit 아이템.
  • 일반적으로 보조 애플리케이션 윈도 상의 File 메뉴에 있는 Close 아이템.
  • 일반적으로 모덜 다이얼로그 박스에 있는 Cancel 버튼.
  • 일반적으로 모덜리스 다이얼로그 박스에 있는 Close 버튼.

위의 개발자 제공의 메커니즘 중 하나에 응답하여 윈도를 닫기 위해, Close 메소드를 호출할 필요가 있습니다.

다음 예제는 File | Exit 메뉴가 클릭되었을 때 어떻게 윈도를 닫는지를 보여줍니다.

XAML
<Window
    x:Class="CustomMediaPlayerWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Custom Media Player"
    Activated="window_Activated"
    Deactivated="window_Deactivated">
  ...
  <MenuItem Header="_File">
      <MenuItem Header="_Exit" Click="exitMenu_Click" />
  </MenuItem>
  ...
</Window>
C#

using System.Windows;

public partial class CustomMediaPlayerWindow : Window

{

    ...

    void exitMenu_Click(object sender, EventArgs e)

    {

        // Close the window

        this.Close();

    }

}

윈도가 닫힐 때, 윈도는 ClosingClosed 이벤트를 띄우게 됩니다.

Closing은 윈도가 닫히기 전에 발생하고, 윈도가 실제로 닫히는 것을 막을 수 있게 합니다. 이렇게 하는 일반적인 이유로는 윈도가 저장되어야 할 데이터를 포함하고 있거나 어떤 활동이 일어나는 경우가 있습니다. 이 상황에서, 윈도는 Closing 이벤트를 사용하여 사용자에게 통지하고 계속해서 윈도를 닫을지 말지 물을 수 있습니다. 본질적으로, 이것은 저장되지 않은 데이터를 포함한 윈도를 닫도록 시도할지 모르는 사용자를 위한 백업 테크닉입니다.

다음과 같이 Closing 처리를 할 수 있습니다.

XAML
<Window
    x:Class="CustomMediaPlayerWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Custom Media Player"
    Activated="window_Activated"
    Deactivated="window_Deactivated"
    Closing="window_Closing">
  ...
</Window>
C#

using System.Windows;

public partial class CustomMediaPlayerWindow : Window

{

    ...

    void window_Closing(object sender, CancelEventArgs e)

    {

        // Ask user if they want to close the window

        if (this.isMediaElementPlaying)

        {

            string msg = "Media is playing. Really close?";

            string title = "Custom Media Player?";

            MessageBoxButton buttons = MessageBoxButton.YesNo;

            MessageBoxImage icon = MessageBoxImage.Warning;


            // Show message box and get user's answer

            MessageBoxResult result =

                MessageBox.Show(msg, title, buttons, icon);


            // Don't close window if user clicked No

            e.Cancel = (result == MessageBoxResult.No);

        }

    }

}

Closing 이벤트 핸들러는 true로 설정하여 윈도 닫기를 막기 위한 Boolean Cancel 속성을 노출하는 CancelEventArgs에 의해 전달됩니다.

Closing이 처리되지 않거나 처리되었지만 취소되지 않았다면, 윈도는 닫힙니다. 윈도를 닫기 직전에, 그리고 Closing이 처리된 후, Closed가 발생됩니다.

노트:
애플리케이션은 메인 윈도가 닫히거나(MainWindow 참고) 마지막 윈도가 닫힐 때 자동적으로 종료될 수 있도록 설정할 수 있습니다. ShutdownMode를 참고합니다.

윈도는 비클라이언트 영역과 클라이언트 영영이 제공하는 메커니즘을 통해 명시적으로 종료될 수 있으며, 또한 다음과 같이 애플리케이션이나 윈도의 다른 부분에 의한 동작의 결과에 의해 묵시적으로 닫힐 수도 있습니다.

  • 사용자가 로그 오프하거나 윈도를 종료하는 경우.
  • 윈도의 소유자가 닫히는 경우(Owner 참고).
  • 메인 애플리케이션 윈도가 닫히고 ShutdownMode가 OnMainWindowClose인 경우.
  • Shutdown이 호출된 경우.
노트:
윈도는 닫힌 이후에 다시 열 수 없습니다.

윈도 라이프타임 이벤트
다음 그림은 윈도의 라이프타임내의 핵심 이벤트와 그것이 발생하는 순서를 나타냅니다.

사용자 삽입 이미지

윈도 위치

윈도가 열리면, LeftTop 속성으로부터 확정될 수 있는 데스크탑(바탕 화면)에 대한 xy 경로를 가집니다. 윈도의 현재 위치를 변경하고 싶다면 이 속성을 설정할 수 있습니다. Window는 또한 처음으로 열려 나타날 때의 위치를 설정할 수 있습니다.

시작 위치
윈도가 열릴 때 윈도가 나타날 위치는 WindowStartupLocation 속성에 의해 결정되며, 다음의 WindowStartupLocation 열거 값중 하나로 설정할 수 있습니다.

시작 위치가 Manual로 지정되면, 윈도는 Windows(운영체제)에 나타날 위치를 물을 것입니다. LeftTop 속성을 사용하여 위치를 지정하는 것으로 이것을 오버라이드 할 수 있습니다.

최상위 윈도와 Z-Order
윈도는 각각 LeftTop 속성으로 지정되는 xy위치를 가지고 있습니다. 추가적으로, 윈도는 다른 윈도에 대한 수직 위치를 결정하는 z 축에 대한 위치를 가집니다. 이것은 z-order로 알려져 있고, 일반(normal) z-order최상위(topmost) z-order의 두 형식을 가집니다. 일반 z-order에 있는 윈도는 언제나 최상위 z-order에 있는 윈도보다 아래에 위치합니다. 최상위 z-order에 위치하기 위해서, 윈도는 반드시 Topmost 속성을 true로 설정해야 합니다.

XAML
<Window ... Topmost="True">
  ...
</Window>

각 z-order에서, 현재 활성 윈도가 같은 z-order에 있는 다른 모든 윈도보다 위에 나타납니다.

다음 그림은 일반과 최상위 z-order에 있는 윈도상에서 Topmost 속성의 효과를 나타냅니다.

사용자 삽입 이미지

윈도 크기

데스크탑에서의 위치를 가지는 것 외에, 윈도는 그것이 보이는 크기를 가집니다. 윈도 크기는 각종 너비와 높이 속성 및 SizeToContent와 같은 몇몇 Window 속성에 의해 결정됩니다.

MinWidth, WidthMaxWidth는 윈도가 그 라이프타임동안 가질 수 있는 너비의 범위를 관리하고, 다음과 같이 설정할 수 있습니다.

XAML
<Window ... MinWidth="300" Width="400" MaxWidth="500">
  ...
</Window>

다음 그림은 어떻게 이 속성들이 윈도의 너비 범위에 적용되는지를 나타냅니다.

사용자 삽입 이미지

윈도 높이는 MinHeight, HeightMaxHeight에 의해 관리되고, 다음과 같이 설정할 수 있습니다.

XAML
<Window ... MinHeight="300" Height="400" MaxHeight="500">
  ...
</Window>

다음 그림은 어떻게 이 속성들이 윈도의 높이 범위에 적용되는지를 나타냅니다.

사용자 삽입 이미지

이러한 너비값과 높이값은 각각 범위를 지정하기 때문에, 크기 변경 가능한 윈도의 너비와 높이는 각 축을 위한 지정된 범위내에서만 지정하는 것이 가능합니다. 현재 너비와 높이는 각각 ActualWidthActualHeight를 조사하여 알 수 있습니다.

윈도의 너비와 높이가 윈도 내용의 크기에 맞출 필요가 있다면, SizeToContent 속성을 사용하여 다음과 같은 값으로 설정할 수 있습니다.

  • Manual. 효과 없음(기본값).
  • Width. 내용의 너비에 맞춤 : MinWidthMaxWidth를 내용의 너비로 설정하는 것과 같은 효과.
  • Height. 내용의 높이에 맞춤 : MinHeightMaxHeight을 내용의 높이로 설정하는 것과 같은 효과.
  • WidthAndHeight. 내용의 너비와 높이에 맞춤 : MinWidth, MaxWidthMinHeight, MaxHeight를 각각 내용의 너비 및 높이로 설정하는 것과 같은 효과.

다음 코드는 윈도가 처음 나타날 때 자동으로 내용의 수직과 수평에 맞춘 크기가 되는 윈도를 보여줍니다.

XAML
<Window ... SizeToContent="WidthAndHeight">
  ...
</Window>

크기 조절 속성의 우선 순위

본래, 윈도의 각 사이즈 속성은 크기 조절 가능한 윈도를 위한 너비와 높이의 범위를 정의하여 조합됩니다. 올바른 범위가 유지될 수 있도록, 윈도는 다음 우선 순위를 사용하여 크기 속성들의 값을 평가합니다.

  • 높이 속성들:
    System.Windows.FrameworkElement.MinHeight >
    System.Windows.FrameworkElement.MaxHeight >
    System.Windows.SizeToContent.Height / System.Windows.SizeToContent.WidthAndHeight >
    System.Windows.FrameworkElement.MaxHeight
  • 너비 속성들:
    System.Windows.FrameworkElement.MinWidth >
    System.Windows.FrameworkElement.MaxWidth >
    System.Windows.SizeToContent.Width / System.Windows.SizeToContent.WidthAndHeight >
    System.Windows.FrameworkElement.MaxWidth

Window Sizing Order of Precedence Sample을 사용하여 우선 순위를 실험해 볼 수 있습니다.

우선 순위는 또한 WindowState 속성으로 관리되는 윈도의 크기가 최대화 되었을 때의 크기도 결정합니다.

윈도 상태

크기 조절 가능한 윈도의 라이프타임동안, 윈도는 보통(normal), 최소화(minimized) 및 최대화(maximized) 상태를 가질 수 있습니다. 보통(normal) 상태의 윈도는 윈도의 기본 상태입니다. 이 상태를 가진 윈도는 현재 보이거나 테두리가 있고 크기 조절이 가능하다면, 사용자가 크기 조절 그립을 사용하여 이동하고 크기를 조절할 수 있게 합니다.

최소화(minimized) 상태의 윈도는 ShowInTaskbartrue로 설정이 되어 있을 경우, 태스크바의 버튼으로 축소합니다. 그렇지 않을 경우, 윈도는 가능한 가장 작은 크기로 축소하고, 자신의 위치를 데스크탑의 좌측 하단 구석으로 변경합니다. 어떤 최소화된 윈도의 종류도 테두리나 크기 조절 그립을 사용하여 크기를 조절하거나, 태스크 바에 있는 최소화된 윈도를 드래그하여 데스크탑으로 돌린다거나 할 수 없습니다. 다음 그림은 최소화된 윈도의 두 종류를 보여줍니다. (※역주 : MSDN! 그림을 빼먹다니! 이 부분은 다들 무슨 얘긴지 아시리라 믿습니다.)

최대화(maximized) 상태의 윈도는 MaxWidth, MaxHeightSizeToContent 속성에서 가능한 최대의 크기로 확장합니다. 최소화된 윈도처럼, 최대화된 윈도도 크기를 변경하거나 드래그할 수 없습니다.

윈도의 상태는 WindowState 속성을 세팅하여 설정할 수 있고, 다음 WindowState 열거 값중 하나의 값을 가집니다.

다음 예제는 어떻게 윈도가 열렸을 때 최대화되어 보이는 윈도를 생성하는지 보여줍니다.

XAML
<Window ... WindowState="Maximized">
  ...
</Window>

일반적으로, 윈도의 초기 상태를 설정하기 위해 WindowState를 설정할 것입니다. 일단 크기 변경 가능한 윈도가 보이면, 사용자는 윈도 상태를 변경하기 위하여 윈도의 타이틀 바에 있는 최소화, 최대화 및 이전 크기로 버튼을 사용할 수 있습니다.

윈도 형태

윈도-지정 내용에 버튼, 라벨 및 텍스트 박스 같은 것을 추가하여 윈도의 클라이언트 영역의 형태를 변경할 수 있습니다. 비클라이언트 영역을 설정하기 위해, Window는 윈도의 아이콘을 설정하기 위한 Icon과 제목을 설정하기 위한 Title과 같은 몇 가지 속성을 제공합니다.

또한 윈도의 resize mode, window style 및 데스크탑의 태스크바에 버튼을 보여줄지 여부를 설정하여 비클라이언트 영역의 형태나 동작을 변경할 수 있습니다.

Resize Mode
WindowStyle에 따라서, 사용자가 윈도의 크기를 변경하거나 다른 모든 것들을 할 수 있는지를 변경할 수 있습니다. 사이즈 조절과 관련하여, 윈도 스타일의 선택은 사용자가 윈도의 테두리를 마우스로 드래그하여 크기를 변경할 수 있을지, Minimize, MaximizeResize 버튼이 비클라이언트 영역에 나타날지, 사용가능한지에 영향을 미칩니다.

ResizeMode 속성을 설정하여 윈도 크기 조절이 어떻게 될지를 설정할 수 있고, 다음 ResizeMode 열거 값중 하나를 가집니다.

다음 그림은 각각의 효과를 나타냅니다.

사용자 삽입 이미지

WindowStyle과 같이, 윈도의 resize mode는 그 라이프타임 동안 변경되지는 않을 것이고, 대부분 마크업에서 그것을 설정할 것이라는 것을 의미합니다.

XAML
<Window ... ResizeMode="CanResizeWithGrip">
    ...
</Window>

윈도가 최대화, 최소화 또는 이전 크기로 되었는지는 WindowState 속성을 조사하여 알 수 있습니다.

Window Style
윈도의 비클라이언트 영역에서 노출되는 테두리는 대부분의 애플리케이션에 적당합니다. 그러나, 윈의 종류에 따라서는, 다른 형태의 테두리가 필요하거나, 전혀 필요하지 않은 상황이 있습니다.

윈도가 가질 테두리의 종류를 컨트롤하기 위해, WindowStyle 속성을 다음과 같은 WindowStyle 열거 값중 하나로 설정할 수 있습니다.

이 윈도 스타일의 효과는 다음 그림에 나타나 있습니다.

사용자 삽입 이미지

WindowStyle은 마크업이나 코드를 사용하여 설정할 수 있지만, 윈도의 라이프타임 동안 그것을 변경할 것 같지는 않으므로 대부분 마크업을 사용하여 설정할 것입니다.

XAML
<Window ... WindowStyle="ToolWindow">
    ...
</Window>

비사각형 윈도 스타일
또한 WindowStyle이 허용하는 테두리 스타일이 충분하지 않은 상황이 있습니다. 예를 들어, Microsoft Windows Media Player가 사용하는 것 처럼, 비사각형 테두리를 가진 애플리케이션을 만들고 싶은 경우가 있습니다.

예를 들어, 다음 그림과 같은 풍선 윈도를 생각해볼 수 있습니다.

사용자 삽입 이미지

이런 종류의 윈도는 WindowStyle 어트리뷰트를 None으로 설정하고, Window가 투명함을 가질 수 있는 특별한 지원을 사용하여 만들 수 있습니다.

XAML
<Window ...
  WindowStyle="None"
  AllowsTransparency="True"
  Background="Transparent">
    ...
</Window>

이것은 WindowStyle, AllowsTransparencyBackground 어트리뷰트의 조합이고 이 값들은 윈도를 완전히 투명하게 그리도록 합니다. 이것은 Path를 사용하여 원하는 테두리를 제공하여 가능합니다. 예를 들면,

XAML
<Window ...
  WindowStyle="None"
  AllowsTransparency="True"
  Background="Transparent">
    ...
    <!-- Path and fill for speech bubble UI -->
    <Path Stroke="DarkGray" StrokeThickness="2">
        ...
    </Path>
    ...
</Window>

윈도를 비사각형 테두리로 생성하였다면, WPF가 제공하는 비클라이언트 영역 요소를 사용할 수 없다는 것을 의미하며, 따라서, 반드시 스스로 구현해야 합니다.

Non-Rectangular Windows Sample을 참고합니다.

태스크바 표시
윈도의 기본 형태는 다음 그림과 같이 태스크바 버튼을 포함합니다.

사용자 삽입 이미지

어떤 윈도는 메시지 박스와 다이얼로그 박스(Dialog Boxes Overview를 참고)와 같이 태스크바 버튼을 가지지 않습니다. 윈도를 위한 태스크바 버튼이 보일지 말지를 ShowInTaskbar 속성(기본값으로 true)을 설정하여 변경할 수 있습니다.

XAML
<Window ... ShowInTaskbar="False">
    ...
</Window>


보안 고려 사항

Window는 인스턴트화 되기 위해 UnmanagedCode 보안 허가를 요구합니다. 로컬 머신에 설치되고 실행되는 애플리케이션을 위해, 이것은 애플리케이션에 부여되는 허가의 세트에 포함됩니다.

그러나, ClickOnce를 사용하여 Internet이나 LocalIntranet에서 시작된 애플리케이션에 부여된 허가의 세트에는 포함되지 않습니다. 따라서, 사용자는 ClickOnce 보안 경고를 받을 것이며, 애플리케이션이 완전히 신뢰되기 위한 허가 세트를 높힐 필요가 있을 것입니다.

추가적으로, XBAPs는 기본적으로 윈도나 다이얼로그 박스를 보일 수 없습니다. 독립 애플리케이션 보안에서의 고려사항을 다루는 WPF Security Strategy - Platform Security를 참고합니다.

See Also

Reference
Window
MeesageBox
NavigationWindow
Application
Concepts
Dialog Boxes Overview
Building a WPF Application

신고
Posted by gongdo


티스토리 툴바