검색결과 리스트
WPF에 해당되는 글 15건
글
WPF 기본 동작구조
저는 C# 을 하다가, WPF 를 접하게 되었습니다.
당시에 생각하기로 XAML 은 단순히 UI 를 ML 을 통해서 작성할 수 있도록 해 주는 보조적인 것으로 생각했습니다.
왜냐면, C# 으로 WPF 프로그래밍이 가능하니까요.
그러다보니, C# 없는 XAML 은 동작이 불가능하다.
"존재 의미가 없다." / "XAML 혼자 동작할 수 없다."
라고 무의식적으로 생각해 왔습니다.
그리고, 당장 개발하기 급급해서 내부적으로 어떻게 동작하는 줄 모르고,
그냥 사용하기에 바빴지요.
그래서, 오늘은 이 부분에 대해서 좀 살펴 보도록 하려 합니다. :)
WPF 빌드 및 동작 구조
먼저 WPF 응용프로그램을 만들었습니다.
App.xaml 과 MainWindow.xaml 이렇게 두개가 생성되었네요.
먼저 App.xaml 을 살펴보도록 하겠습니다.
왜냐면, 이게 프로그램의 Entry Point 니까요.
<Application x:Class="WPFApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
가장 처음 WPF(XAML) 를 접했을때, '뭐가 이렇게 네임스페이스가 많아?' 라고 생각했습니다. :)
xmlns 과 xmlns:x 는 clr 에서 정의된 내용이라고 추측하고 있습니다.
(이 부분에 대해서는 자료를 좀 찾아보려 했는데, 잘 보이지 않네요.)
모쪼록 이 두개의 네임스페이스는 꼭 필요하다고만 짚고 넘어가겠습니다.
x:Class 가 하는 일은?
x:Class 는 역시나 clr 내부적으로 정의된 부분인것으로 추측되는데요.
msdn 에 살펴보면,
In markup, the Application element must include the x:Class attribute. When the application is built, the existence of x:Class in the markup file causes MSBuild to create a partial class that derives from Application and has the name that is specified by the x:Class attribute. This requires the addition of an XML namespace declaration for the XAML schema (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml").
이렇게 설명되어 있습니다.
MSBuild 가 자동으로 x:Class 에 정의된 클래스의 partial 클래스를 생성해 준다고 되어 있습니다.
바로 '*.g.i.cs' 라는 확장자로 된 파일을 말하는 것이지요.
그럼 그 파일을 열어보죠.
public partial class App : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public void InitializeComponent() {
#line 4 "..\..\App.xaml"
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public static void Main() {
WPFApplication.App app = new WPFApplication.App();
app.InitializeComponent();
app.Run();
}
}
바로 이것이 MSBuild 가 생성한 파일입니다.
Main 함수를 제외하면, 결국 자동생성된 내용은 InitializeComponent() 이 되겠습니다.
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
이 한줄인데, Application 에 StartupUri 프로퍼티를 set 해주는게 전부입니다.
잠깐!
StartupUri 프로퍼티를 어디서 본것 같지 않나요?
맞습니다. App.xaml 에서 정의되어 있었지요.
여기서 우리는 다음 사실을 유추해 낼 수 있습니다.
1. MSBuild 는 XAML 코드를 읽고, xmlns 를 확인한다.
2. x:Class 로 정의된 값이 있는지 확인한다.
3. x:Class 가 존재하면, 해당 클래스의 partial 을 생성한다.
4. partial 에 XAML 코드에 작성된 것을 바탕으로 코드를 자동생성한다.
x:Class 를 삭제한다면?
그럼 테스트를 한번 해 보도록 합시다.
App.xaml 에서 x:Class 부분을 삭제하고, 빌드해 보도록 하겠습니다.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
[삭제 전]
[삭제 후]
보시는 것 처럼, partial 인 App.g.i.cs 파일이 통째로 삭제되었습니다.
덕분에 Main 메소드까지 사라졌네요.
이로서, MSBuild 가 XAML 을 바탕으로, x:Class 에 정의된 클래스의 partial 을 자동생성 해 준다는 사실을 확인하였습니다.
그런데!
Main 메소드가 없이도 실행이 된다?
Main 이 없어졌다면.. 프로그램은 어떻게 실행될까요? 아니 빌드는 될까요? 실행은 될까요?
신기하게도, 빌드도 정상적으로 되고, 실행도 잘 됩니다. :)
이유는 솔루션 탐색기에서 노출이 안되는 것 뿐이고, App.g.i.cs 는 여전히 어딘가에 살아 있습니다.
그리고 그 코드를 보면, 요렇게 바뀌어 있습니다.
#pragma checksum "..\..\App.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "6A5D1236E94AE7445F15103C4E132DF4"
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18444
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Shell;
namespace XamlGeneratedNamespace {
/// <summary>
/// GeneratedApplication
/// </summary>
public partial class GeneratedApplication : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public void InitializeComponent() {
#line 4 "..\..\App.xaml"
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public static void Main() {
XamlGeneratedNamespace.GeneratedApplication app = new XamlGeneratedNamespace.GeneratedApplication();
app.InitializeComponent();
app.Run();
}
}
}
바뀐부분은 아래 코드 한줄이네요.
[삭제 전]
WPFApplication.App app = new WPFApplication.App();
[삭제 후]
XamlGeneratedNamespace.GeneratedApplication app = new XamlGeneratedNamespace.GeneratedApplication();
App 과 GeneratedApplication 의 차이는 그냥 Class 이름이 변경된것 뿐입니다.
(Framework 에 있는 클래스가 아니라, 코드를 잘 보시면 아시겠지만, 그냥 자기 자신 클래스 이름입니다.)
즉, App.xaml 에 대해서는 명시적으로 x:Class 를 써 주느냐, 마느냐의 차이 밖엔 없는것으로 보여집니다.
App.xaml 을 아래처럼 수정하고, x:Class 를 정의한 상태에서 빌드. 삭제한 상태에서 빌드. 각각 비교해 보면,
App 이 GeneratedApplication 으로 바뀌는것 이외에는 차이가 없음을 알 수 있습니다.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Red"/>
</Style>
</Application.Resources>
</Application>
StartupUri 가 없다면?
이번엔 한번 App.xaml 에서 StartupUri 설정 부분을 삭제하고 빌드해 보죠.
다음처럼 App.g.i.cs 가 바뀌었습니다.
/// <summary>
/// GeneratedApplication
/// </summary>
public partial class GeneratedApplication : System.Windows.Application {
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public static void Main() {
XamlGeneratedNamespace.GeneratedApplication app = new XamlGeneratedNamespace.GeneratedApplication();
app.Run();
}
}
역시 MSBuild 에 의해서 XAML 이 해석되고, 이를 바탕으로 partial 클래스가 생성되는 것이 맞네요.
이 상태에서 실행하면, StartupUri 가 없기 때문에, 프로세스는 생성되지만 화면에는 아무것도 노출되지 않습니다.
다음에는 MainWindow.xaml 부분을 이것저것 수정하여, 테스트 해 보도록 하겠습니다.
'Microsoft > WPF' 카테고리의 다른 글
TypeConverter (0) | 2014.05.12 |
---|---|
XAML 의 문법구조 (0) | 2014.05.12 |
xaml 과 cs 파일의 관계 (1) | 2014.05.08 |
WPF 3D Tutorial (7) | 2011.04.09 |
Animated Image (0) | 2010.12.10 |
RECENT COMMENT