MSDN : http://msdn2.microsoft.com/en-us/library/ms748948.aspx
WPF Windows Overview
사용자는 WPF 독립 애플리케이션과 주로 시각화한 데이터 컨텐트를 보여주고 사용자를 데이터와 상호작용 할 수 있도록 하는 윈도를 통하여 상호작용 합니다.
이 토픽은 다음 섹션을 담고 있습니다.
Window 클래스
다음 그림은 일반적인 윈도의 요소를 나타냅니다.
윈도는 비클라이언트 영역과 클라이언트 영역의 두 영영으로 나뉩니다.
윈도의 비클라이언트 영역은 WPF에 의해 구현되고, 대부분의 윈도에게 공통적인 다음과 같은 요소를 포함합니다.
- 테두리(border)
- 타이틀 바
- 아이콘
- 최소화, 최대화 및 원래 크기로 버튼
- 닫기 버튼
- 최소화, 최대화, 원래 크기로, 이동, 크기 조정 및 닫기를 위한 메뉴 아이템을 제공하는 시스템 메뉴
윈도의 클라이언트 영역은 윈도의 비클라이언트 영역 내의 영역이고, 윈도-정의(window-specific)내용을 표현하기 위해 개발자가 사용합니다.
WPF에서, 윈도는 다음과 같은 것을 가능케하는 Window 클래스에 의해 캡슐화됩니다.
- 윈도의 크기, 위치 및 형태를 설정.
- 윈도 내에 내용을 얹음.
- 윈도를 보여줌.
- 윈도의 라이프타임을 관리
메시지 박스와 다이얼로그 박스는 윈도의 다른 형식이며 Dialog Boxex Overview에서 다룹니다. 또한, NavigationWindow는 Window에서 상속된 윈도의 특별한 형식이며 컨텐트를 표시하고 운항(네비게이션)하기 위한 지원을 확장합니다(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)가 붙은 것과 같은 이름을 갖습니다. 이 접미어는 마이크로소프트 비주얼 스튜디오가 기본적으로 이런 규칙을 사용하긴 하지만 반드시 필요하진 않습니다.
노트:
윈도 라이프타임
한 번 윈도가 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 이벤트가 발생된 후
Loaded와
ContentRendered 이벤트가 발생합니다. 따라서, 윈도는
ContentRendered가 발생하였을 때만 열려야 할지를 고려해야 합니다.
윈도가 활성화 된 후, 사용자는 같은 애플리케이션 내의 또 다른 윈도를 활성화 하거나 다른 애플리케이션을 활성화 할 수 있습니다. 그랬을 때, 현재 활성 윈도는 비활성화 되고 Deactivated 이벤트를 띄웁니다.
Activated와 Deactivated를 처리하는 한 가지 이유는 예를 들어, 게임이나 비디오 플레이어와 같이 끊임 없는 사용자의 입력이나 집중이 필요한 윈도가 활성화 되었을 때에만 동작할 수 있는 기능을 사용 가능 또는 사용 불가능하게 하기 위해서 입니다.
다음 예제는 이 동작을 구현하기 위해 어떻게 Activated와 Deactivated를 처리하는지 보여줍니다.
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();
}
}
노트:
때로, 윈도는 활성 윈도가 아닐지라도 코드를 계속 실행해야 할지도 모릅니다. 예를 들어, 메일 클라이언트는 사용자가 다른 애플리케이션을 사용하는 동안 메일 서버를 지속적으로 폴링할 것입니다. 이와 같은 애플리케이션은 종종 메인 윈도가 비활성화 되었을 때 다른, 혹은 추가적인 동작을 제공합니다. 메일 프로그램의 경우를 고려해봤을 때, 이것은 새 메일을 받은 편지함에 추가하는 것 뿐만 아니라, 사용자에게 통지하기 위한 시스템 트레이에 아이콘을 추가하는 것도 의미합니다. 애플리케이션이 이런 동작을 수행할 필요가 있는지를 결정하기 위해, IsActive 속성을 검사하여 윈도가 활성화 되었는지 아닌지를 검출할 수 있습니다.
다른 경우, 윈도는 특별히 더 긴급하게 사용자에게 통지를 할 필요가 있다면, 활성 윈도가 되길 원할 것입니다. 이것은 Activate 메소드를 호출하여 가능합니다.
노트 :
윈도 닫기
사용자가 윈도 사용을 마쳤을 때, 그것을 닫길 바랄 것입니다. 윈도는 다음과 같은 비클라이언트 영역의 요소를 사용하여 닫을 수 있습니다.
- 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();
}
}
윈도가 닫힐 때, 윈도는 Closing과 Closed 이벤트를 띄우게 됩니다.
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이 호출된 경우.
노트:
윈도는 닫힌 이후에 다시 열 수 없습니다.
윈도 라이프타임 이벤트
다음 그림은 윈도의 라이프타임내의 핵심 이벤트와 그것이 발생하는 순서를 나타냅니다.
윈도 위치
윈도가 열리면, Left와 Top 속성으로부터 확정될 수 있는 데스크탑(바탕 화면)에 대한 x와 y 경로를 가집니다. 윈도의 현재 위치를 변경하고 싶다면 이 속성을 설정할 수 있습니다. Window는 또한 처음으로 열려 나타날 때의 위치를 설정할 수 있습니다.
시작 위치
윈도가 열릴 때 윈도가 나타날 위치는 WindowStartupLocation 속성에 의해 결정되며, 다음의 WindowStartupLocation 열거 값중 하나로 설정할 수 있습니다.
시작 위치가 Manual로 지정되면, 윈도는 Windows(운영체제)에 나타날 위치를 물을 것입니다. Left와 Top 속성을 사용하여 위치를 지정하는 것으로 이것을 오버라이드 할 수 있습니다.
최상위 윈도와 Z-Order
윈도는 각각 Left와 Top 속성으로 지정되는 x와 y위치를 가지고 있습니다. 추가적으로, 윈도는 다른 윈도에 대한 수직 위치를 결정하는 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, Width 및 MaxWidth는 윈도가 그 라이프타임동안 가질 수 있는 너비의 범위를 관리하고, 다음과 같이 설정할 수 있습니다.
XAML
<Window ... MinWidth="300" Width="400" MaxWidth="500">
...
</Window>
다음 그림은 어떻게 이 속성들이 윈도의 너비 범위에 적용되는지를 나타냅니다.
윈도 높이는 MinHeight, Height 및 MaxHeight에 의해 관리되고, 다음과 같이 설정할 수 있습니다.
XAML
<Window ... MinHeight="300" Height="400" MaxHeight="500">
...
</Window>
다음 그림은 어떻게 이 속성들이 윈도의 높이 범위에 적용되는지를 나타냅니다.
이러한 너비값과 높이값은 각각 범위를 지정하기 때문에, 크기 변경 가능한 윈도의 너비와 높이는 각 축을 위한 지정된 범위내에서만 지정하는 것이 가능합니다. 현재 너비와 높이는 각각 ActualWidth와 ActualHeight를 조사하여 알 수 있습니다.
윈도의 너비와 높이가 윈도 내용의 크기에 맞출 필요가 있다면, SizeToContent 속성을 사용하여 다음과 같은 값으로 설정할 수 있습니다.
- Manual. 효과 없음(기본값).
- Width. 내용의 너비에 맞춤 : MinWidth와 MaxWidth를 내용의 너비로 설정하는 것과 같은 효과.
- Height. 내용의 높이에 맞춤 : MinHeight과 MaxHeight을 내용의 높이로 설정하는 것과 같은 효과.
- WidthAndHeight. 내용의 너비와 높이에 맞춤 : MinWidth, MaxWidth 및 MinHeight, 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) 상태의 윈도는 ShowInTaskbar가 true로 설정이 되어 있을 경우, 태스크바의 버튼으로 축소합니다. 그렇지 않을 경우, 윈도는 가능한 가장 작은 크기로 축소하고, 자신의 위치를 데스크탑의 좌측 하단 구석으로 변경합니다. 어떤 최소화된 윈도의 종류도 테두리나 크기 조절 그립을 사용하여 크기를 조절하거나, 태스크 바에 있는 최소화된 윈도를 드래그하여 데스크탑으로 돌린다거나 할 수 없습니다. 다음 그림은 최소화된 윈도의 두 종류를 보여줍니다. (※역주 : MSDN! 그림을 빼먹다니! 이 부분은 다들 무슨 얘긴지 아시리라 믿습니다.)
최대화(maximized) 상태의 윈도는 MaxWidth, MaxHeight 및 SizeToContent 속성에서 가능한 최대의 크기로 확장합니다. 최소화된 윈도처럼, 최대화된 윈도도 크기를 변경하거나 드래그할 수 없습니다.
윈도의 상태는 WindowState 속성을 세팅하여 설정할 수 있고, 다음 WindowState 열거 값중 하나의 값을 가집니다.
다음 예제는 어떻게 윈도가 열렸을 때 최대화되어 보이는 윈도를 생성하는지 보여줍니다.
XAML
<Window ... WindowState="Maximized">
...
</Window>
일반적으로, 윈도의 초기 상태를 설정하기 위해 WindowState를 설정할 것입니다. 일단 크기 변경 가능한 윈도가 보이면, 사용자는 윈도 상태를 변경하기 위하여 윈도의 타이틀 바에 있는 최소화, 최대화 및 이전 크기로 버튼을 사용할 수 있습니다.
윈도 형태
윈도-지정 내용에 버튼, 라벨 및 텍스트 박스 같은 것을 추가하여 윈도의 클라이언트 영역의 형태를 변경할 수 있습니다. 비클라이언트 영역을 설정하기 위해, Window는 윈도의 아이콘을 설정하기 위한 Icon과 제목을 설정하기 위한 Title과 같은 몇 가지 속성을 제공합니다.
또한 윈도의 resize mode, window style 및 데스크탑의 태스크바에 버튼을 보여줄지 여부를 설정하여 비클라이언트 영역의 형태나 동작을 변경할 수 있습니다.
Resize Mode
WindowStyle에 따라서, 사용자가 윈도의 크기를 변경하거나 다른 모든 것들을 할 수 있는지를 변경할 수 있습니다. 사이즈 조절과 관련하여, 윈도 스타일의 선택은 사용자가 윈도의 테두리를 마우스로 드래그하여 크기를 변경할 수 있을지, Minimize, Maximize 및 Resize 버튼이 비클라이언트 영역에 나타날지, 사용가능한지에 영향을 미칩니다.
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, AllowsTransparency 및 Background 어트리뷰트의 조합이고 이 값들은 윈도를 완전히 투명하게 그리도록 합니다. 이것은 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
Submit comment.
비밀댓글입니다
비밀댓글입니다
한줄마다 공백 끼워넣어서 장문을 만드는 꼼수!
전 생각나는 이야기가 2005는 VS+SQL의 관점이었다면 2008에서는 VS+Server의 관점이라는 말이 기억이 많이 나더라고요.
2008년 제품중에 SQL 2008 카트마이도 있어요. -_-''
2008년 진정한 대박이 되지 않을까 싶네요.
[아이뉴스 24] MS, 윈도서버·SQL서버·비주얼스튜디오2008 내년 2월 출시 (http://www.serverinfo.pe.kr/News.aspx?Seq=310)
기획자는 웁니다~ T.T
개발 기술이 발전함에 따라 기획자들이 파악해야 하는 기술들도 하나둘씩 늘어만 가네요..
개인적으로 실버라이트의 소식을 듣고자 들어왔다가 울며 갑니다 ^-^;;;
반갑습니다. :)
아마 한동안(대략 1~2년쯤?)은 웹환경이 굉장히 크게 흔들릴 것 같고 이후 윈도의 차기 버전이 나오고 Win32를 탈피할 때쯤이면 데스크탑 환경이 또 엄청나게 크게 흔들릴것 같아요. 개발자들도 파도타기를 하는 기분이죠. 하핫!
다른것들은 다 두고서라도 ASP 및 기존 웹개발자들에게 당시 2001년 아마도 여름의 뜨거운 태양이 지고 가을이 올 무렵으로 기억합니다. 당시 Visual Studio.net(이하 VS~) 베타버전이 출시되었을때 시장은 지금과는 사믓 다르게 냉담하였습니다. 기존 웹프로그래밍과 asp.net이 얼마나 차별성이 있을지 또 개발생산성이 극대화 될지 등등에 대한 이유였습니다. 이후에도 2002년도에 VS.NET 2002(1.0)와 2003년 VS.NET 2003(1.1)이 연속으로 정식 릴리즈 되었지만 약 2년정도는 시장의 반응은 냉담하고 참혹할정도였습니다.
여기서 중요한건 새로운 기술이 나와서 그 기술이 대중화 될때까지 걸리는 시각이 약 2~3년정도 걸린다고 봤을때 현재 VS.NET 2005(2.x)가 나온지 2년이 채 지나지 않았습니다. 즉, 아직 시장에서 뿌리를 내리지도 못하고 VS.NET 2008이 나올 준비를 하고 있습니다.
정말 의구심이 드는것은 상당수의 회사들이 프로젝트 개발툴을 VS2003에서 VS2005로 변경하였지만 과연 VS2005의 기술들이 얼마나 프로젝트에 많이 녹아있는지 알 수 없다라는 점입니다. 정말 제대로된 몇몇 회사말고는 단지 껍데기만 VS2003에서 VS2005로 갈아입었을뿐 프레임워크내의 코드 및 프로젝트 특징은 전혀 바뀌지 않았다는 것입니다. VS2005의 장점과 특징을 전혀 살리지 못하고 하위버전에서 했던 작업을 똑같이 하고 있다는 이야기 입니다. 이것보다 더 문제인것은 아직도 VS2003을 사용하는 곳이 더 많고 상위버전으로 업그레이드 해야할 필요성을 느끼지 못한다는 것입니다.
닷넷시장 전반에 VS2003이 널이 퍼져있고, VS2005는 점점 채택하고 있는 곳은 많으나 개발효용성및 개발생산성에 대한 정확한 분석이 나오지 않은 시점에서 VS2008이 출시를 기다리고 있습니다.
저도 VS2008에 대한 기대는 오래전부터 가지고 있으나 시장에서 2008에 대한 수요가 확산이 되고 대중화 되려면 최소 2년이상의 시간이 걸린다고 봅니다. 그때가 되면 Visual Studio에 대한 신버전에 대한 이야기가 흘러나오고 있겠죠...
저의 개인적인 생각은 근래 3~4년동안 세미나, 데브데이, 컨퍼런스등 많은 행사장을 돌아다녔지만 VS2003 출시이후 VS2005가 나오면서 당시 몇개월도 지나지 않아 VS2005에 대한 차기버전 이야기가 시장에 돌고 있었습니다. 애초에 VS2005가 나오지 않고 VS2008이 약 지금보다 약 1년정도 일찍 출시되었더라면 닷넷시장의 VS 버전에 대한 혼란은 없었을거라 생각합니다.
네, 제가 6년 전에 ASP를 하다가 이번에 처음으로 ASP.NET을 접했을 때 느낀 점이라면 몇가지 기능적인 활용을 제외하곤 ASP때나 지금이나 개발 방식의 차이는 별로 안난다는 것이었어요. 뭐... 이게 HTML기반의 웹의 한계인지 국내 개발 마인드의 한계인지는 잘 모르겠고 어떻게 개선할 수 있을지 제시할 수 있는 실력이나 경험이 있는것도 아니지만요.
어쨌든, 2008은 여러모로 기대되는 해이고 이 지긋지긋한 웹 개발방식에 변화가 왔으면 해요.
참석해서 세미나 잘 보았습니다.
그런데 대부분이 데모중심 이었습니다.
사실 데모는 관련 링크만 준비된다면 꼭 세미나에서 볼 필요는 없다고 생각합니다.
이번 세미나에서는 먼가 다른 줄 알았지만 결국 데모 중심인 세미나였습니다.
개발자를 위한 세미나라면 데모가 아닌 개발방법 이나 팁 위주의
세미나를 준비해 주시기 바랍니다. 단지 광고가 아닌...
그럼 이만... 수고하세요.
네, 의견 감사합니다.
하지만 짧은 시간 동안 기술적인 이슈들이나 방법을 얘기한다는 것은 굉장히 무리가 있는 일이에요.
그래서 세미나는 대략적인 흐름이나 간단한 데모를 바탕으로한 소개 위주로 진행이 되고 세부적인 기술적 이슈들은 세미나 후에 올라갈 자료들을 바탕으로 커뮤니티에서 논의될 수 있도록 하고 있어요.
세미나에는 다양한 스펙트럼을 가진 분들이 찾아오시고 이 분들을 모두 만족시킨다는 것은 불가능하기 때문에 이런 방향으로 진행된다는 것을 이해해주셨으면 하고요, 좀더 기술적인 내용을 어떻게 다뤄야할지는 고민해보도록 할께요.
그런데... 댓글 달고보니 HOONS세미나 얘기가 아니고 MSDN 세미나 얘기를 하신거였나요? 아니면 둘다?
혹시 후자라면 전 MSDN세미나하고 관계 없는 사람인데 번지수를 잘못 짚으신 것 같네요^^;;