xaml 과 cs 파일의 관계






이쯤에서 "WPF 는 C#코드 없이 XAML 만 가지고 동작이 가능한가?" 라는 질문에 대해서 테스트 해 보도록 하겠습니다.

코드는 본래 처음으로 되돌리고, MainWindow.xaml 을 수정해 보겠습니다.



버튼을 넣어 봅시다.


먼저 Window 에 버튼을 하나 넣도록 하겠습니다.



    [MainWindow.xaml]


<Window x:Class="WPFApplication.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>
        <Button Content="My Button"/>
    </Grid>
</Window>





실행하면 버튼이 들어있는 창이 보입니다.






*.cs 를 삭제하고, xaml 만 남겨 봅시다.



이제, 소스코드에서 x:Class 부분을 삭제하고, 탐색기에서 MainWindow.cs 파일도 삭제합니다.

더불어 App.cs 도 삭제합니다.


    [x:Class 삭제]


<Window
        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>
        <Button Content="My Button"/>
    </Grid>
</Window>








보시는 것 처럼, xaml 파일 두개만 남았습니다.

모든 *.cs 파일을 삭제하였습니다.

(사실 App.xaml 은 지난번 테스트했듯이, 내부적으로 cs 파일이 생성됩니다.)



빌드하고, 실행합니다.


어떤가요?

처음 실행했을 때와 동일하게 정상적으로 프로그램이 실행됩니다.



순수하게 UI 만 구성하기 위해서는 CS 파일이 필요가 없다는게 확인 되었네요.

다시말해 View 와 Controller 가 분리되어 있다고 할 수 있겠습니다.




*.cs 파일은 어떤 경우에 필요한가?


그럼 *.cs 파일은 어떤 경우 필요할까요?

버튼 클릭시 메세지박스가 뜨도록 해 봅시다.



    [click 이벤트 추가]


<Window
        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>
        <Button Content="My Button" Click="OnButtonClick"/>
    </Grid>
</Window>



이벤트 핸들러는 달았으나, 구현할 방법이 없습니다.

x:Class 를 추가해 봅시다.



    [x:Class 추가]


<Window x:Class="WPFApplication.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>
        <Button Content="My Button" Click="OnButtonClick"/>
    </Grid>
</Window>




MainWindow.cs 파일을 생성해 준 뒤, 빌드를 하면, 자동으로 xaml 과 코드가 연결됩니다.

핸들러는 MessageBox 가 뜨도록 작성하였습니다.



    [MainWindow.cs]


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;


namespace WPFApplication
{
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }


        private void OnButtonClick(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Clicked");
        }
    }
}




이제 xaml 로부터 어떤 코드가 자동으로 작성되었는지 확인해 보겠습니다.


    [MainWindow.g.i.cs]


namespace WPFApplication {
    
    
    /// <summary>
    /// MainWindow
    /// </summary>
    public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {
        
        private bool _contentLoaded;
        
        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
        public void InitializeComponent() {
            if (_contentLoaded) {
                return;
            }
            _contentLoaded = true;
            System.Uri resourceLocater = new System.Uri("/WPFApplication;component/mainwindow.xaml", System.UriKind.Relative);
            
            #line 1 "..\..\MainWindow.xaml"
            System.Windows.Application.LoadComponent(this, resourceLocater);
            
            #line default
            #line hidden
        }
        
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
        void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
            switch (connectionId)
            {
            case 1:
            
            #line 6 "..\..\MainWindow.xaml"
            ((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnButtonClick);
            
            #line default
            #line hidden
            return;
            }
            this._contentLoaded = true;
        }
    }
}



보시는것처럼, IComponentConnector 에 있는 두개의 메소드가 자동 구현되었습니다.

각 메소드가 하는 일은 MSDN 을 찾아보면 쉽게 알 수 있습니다.




Connect 는 말 그대로 x:Name 이나 Click 과 같이, 이름 또는 이벤트를 연결해 주는 코드를 생성합니다.

그리고 InitializeComponent 는 컴파일된 페이지의 컴퍼넌트들을 로드합니다.



즉, 핵심코드는 다음 두 줄이 되겠습니다.


System.Uri resourceLocater = new System.Uri("/WPFApplication;component/mainwindow.xaml", System.UriKind.Relative);

System.Windows.Application.LoadComponent(this, resourceLocater);



((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnButtonClick);




결론


요컨데, xaml 은 wpf(view) 의 핵심이며, *.cs 파일(x:Class 에 선언된)을 Logic 을 위한 코드정도가 되겠네요.





'Microsoft > WPF' 카테고리의 다른 글

TypeConverter  (0) 2014.05.12
XAML 의 문법구조  (0) 2014.05.12
xaml 과 cs 파일의 관계  (1) 2014.05.08
WPF 기본 동작구조  (0) 2014.05.08
WPF 3D Tutorial  (5) 2011.04.09
Animated Image  (0) 2010.12.10
  • 나그네 2021.05.27 11:37

    App.xaml 은 빌드시 자동으로 C# 코드로 변환되어 컴파일되며
    UI 단 xaml 은 baml 로 변한되어 리소스에 위치하게 됩니다. UI xaml 은 실버라이트(지금은 익스에서만 동작함), 윈도우 스타일 앱에서도 똑같이 쓰는데 CS 파일들을 분석해본 결과 WPF 한정으로 자바의 JavaFX 비슷하게 동작하더라고요
    * WPF : main 메소드 있는 클래스 통해서 Xaml 로드하여 UI 직접 뛰우고, UI xaml 에 코드 입력가능, UI xaml은 baml 로컴파일되며
    소스 파일 분리시 UI 와 엮여있는 클래스에서 독특한 방식으로 컴포넌트와 컴포넌트 변수 및 이벤트 핸들러들을 바인딩함
    실버라이트 : 메인 UI는 메인 UI xaml 을 로드하는 메인 UI 용 클래스를 생성하여 바인딩하는 방식으로 뛰움(UI 용 소스파일 필수), UI xaml 은 단지 UI를 그리기 위해서만 사용하며, 바인딩은 안드로이드와 유사한방식으로 하며 UI xaml 에 소스 코드 입력불가하며 baml 변환없이 xaml 째로 리소스 영역으로 들어감
    윈도우 스타일 앱은 실버라이트와 비슷하나 하나의 파일로 컴파일되는 구조가 아니며(xaml이 외부에 있음) 다룬부분이 몇군데 존제함(분석중)

    비쥬얼 스튜디오 없이 빌드툴(2017 버전 사용)로 간단하게 코드 비하인드 방식으로 만들고 컴파일해보니 컴파일할때 바인딩은 자동으로 되는듯합니다. 연결된 소스파일에서 컴포넌트(Button 등) 선언과 InitializeComponent 메소드 부분및 Connect 구현 없이도 동작이 정상적으로 되는것을 확인하였습니다.(연결된 소스에서는 Window 만 상속하였음) => 추가적으로 확인해보니 UI xaml 파일을 기반으로 [Xaml 파일명].g.cs 을 빌드할때 생성하여 껴넣네요 그리고 이파일안에 컴포넌트(Button 등) 선언과 InitializeComponent 메소드 부분및 Connect 구현 및 Xaml 안에 넣는 코드가 들어가는 구조네요