Introduction to XAMLKim, Hyunyoung (young_kim@kaist.ac.kr)Digital Media Lab.2010-07-07
KeywordsWPFXMLXAMLWindow 엘리먼트프로퍼티약간은 불필요한 시도
19장 XAML
XAML [zæ:mɛl]WPF (Window Presentation Foundation)인터페이스와 비즈니스 로직을 분명히 구분응용 프로그램 서비스의 호스트를 통일: 인터페이스, 애니메이션, 3D, 오디오 등XML (Extensible Markup Language)XAML (Extensible Application Markup Language)마이크로소프트에서 구조값과 객체를 초기화하는데 사용하기 위해 만든 선언형XML 기반 언어WPF 의 사용자 인터페이스를 위한 언어런타임 속성편집 도구의 자유: 비주얼 스튜디오, 익스프레션블렌드, 메모장의사소통: 개발자와 디자이너 간에 콘텐츠를 자유롭게 공유하고 편집 가능C# 코드로 표현 가능System.Windows.Controls<Button Foreground=“Yellow” FontSize=“24pt”>	Hello, XAML!</Button>Button btn = new Button();btn.Foreground = Brushes.Yellow;btn.FontSize = 32;		// 장치 독립적 단위btn.Content = “Hello, XAML!”
Stand Alone XAML두 문서에 같은 엘리먼트 이름을서로 다른 목적으로 사용하는 경우WPF 프로그래머의 XAML 문서 & 셔츠 버튼 제조업자의 XML 문서	xmlns: XML 네임스페이스 속성엘리먼트와 자식 엘리먼트에게 적용유일하고 영속적,URL을 사용하는 것이 일반적예제XamlStackPanel.xamlPresentationHost.exe인터넷 익스플로러에 의해 호스팅될 수 있는 Page타입의 객체를 생성로드된XAML을 실제 StackPanel, Button등객체로 변환한 후 이 객체를 Page의 컨텐트 프로퍼티에 저장<Button Foreground=“Yellow” FontSize=“24pt”>	Hello, XAML!</Button>http://schemas.microsoft.com/winfx/2006/xaml/presentation
페이지 속성 변경예제 XamlPage.xamlPage를 루트 엘리먼트로 생성하고 WindowTitle프로퍼티에 원하는 텍스트를 설정StackPanel을 Page의 자식으로 생성Window를 루트 엘리먼트로 한 스탠드얼론XAML은 불가능PresentationHost.exe는 스탠드얼론 XAML 파일의 루트 엘리먼트를 어떤 것의 자식으로 만듦Window객체는 그 어떤 것의 자식도 될 수 없음루트 엘리먼트는Window를 제외하고 FrameworkElement를 상속받는 것이면 어떤 것도 가능
XamlReader.LoadXamlReader.Load메소드System.Windows.Markup네임스페이스XAML을 파싱해 초기화된 객체로 전환XamlWriter.Save는 객체로부터 XAML을 생성Stream 객체나 XmlReader객체를 받음string strXaml ="<Button xmlns='http://schemas.microsoft.com/winfx/2006/" +"	xaml/presentation'" +"	Foreground='LightSeaGreen' FontSize='24pt'>" +"Click me!" +"</Button>";StringReaderstrreader = new StringReader(strXaml);XmlTextReaderxmlreader = new XmlTextReader(strreader);object obj = XamlReader.Load(xmlreader);
XAML을 리소스로 사용하기LoadXamlResource.xmlButton객체에 Name속성 포함LoadXamlResource.csStream 객체가 XamlReader.Load의 인자가 되어 반환되는 객체(StackPanel)를 Window의Content프로퍼티에 할당일단 객체가 XAML로부터 변환되어 창의 비주얼트리의 일부가 되면 FindName메소드를 사용해서 엘리먼트트리상에서 특정한 이름으로 찾는 것이 가능실행 시에 로드한XAML에게 이벤트 핸들러를 연결할 수 있는 가장 간단한 방법<Button Name="MyButton" HorizontalAlignment="Center" Margin="24">Hello, XAML!</Button>Uri uri = new Uri("pack://application:,,,/LoadXamlResource.xml");Stream stream = Application.GetResourceStream(uri).Stream;FrameworkElement el = XamlReader.Load(stream) as FrameworkElement;Content = el;Button btn = el.FindName("MyButton") as Button;if (btn != null)btn.Click += ButtonOnClick;
Window가 루트인 XamlLoadXamlWindow.xmlLoadXamlWindow.csPresentationHost.exe는 XAML을 어떤 것의 자식으로 변환여기서는 XAML 리소스가 Window임을 인식, Window를 상속받거나 Window자체를 직접 생성하지 않음버튼 클릭 이벤트 핸들러를비주얼 트리 속에서 찾아 연결하지 않고 Window의 AddHandler를 호출해 연결Main메소드는Application의 Run메소드에Window객체를 인자로 전달<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        Title="Load Xaml Window"SizeToContent="WidthAndHeight"ResizeMode="CanMinimize">Uri uri = new Uri("pack://application:,,,/LoadXamlWindow.xml");Stream stream = Application.GetResourceStream(uri).Stream;Window win = XamlReader.Load(stream) as Window;win.AddHandler(Button.ClickEvent, 	new RoutedEventHandler(ButtonOnClick));app.Run(win);
XAML을 C#에서 로드하기파일명은 XmlTextReader생성자로 바로 전달객체가 Window이면 모달리스 대화상자처럼 보임XmlTextReaderxmlreader = new XmlTextReader(dlg.FileName);object obj = XamlReader.Load(xmlreader);if (obj is Window){Window win = obj as Window;win.Owner = this;win.Show();}Elseframe.Content = obj;
XAML실제 애플리케이션에서는 XAML을 소스 코드와 함께 컴파일 하는 것이 보편적, 효율적XAML 안에 이벤트 핸들러 이름을 직접 명시가능지금까지 본 XAMLWPF의 클래스와 프로퍼티만을 사용그러나 XAML은 WPF만을 위한 마크업 언어는 아님 (예: Windows Workflow Foundation, WPF)http://schemas.microsoft.com/winfx/2006/xaml: XAML 명세WPF에서 사용XAML 고유 엘리먼트와 속성을 위한 네임스페이스는 관례적으로 접두어x와 함께 선언고유 엘리먼트와 속성이 많지 않아 WPF 관련 네임스페이스가 기본xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:x=http://schemas.microsoft.com/winfx/2006/xaml/presentation
Class속성Class 속성XAML 파일의 루트 엘리먼트XAML이 프로젝트 일부로 컴파일될 때만 사용 가능CompileXamlWindow.xamlXAML 과 비하인드 코드는 하나의 클래스x:Class="MyNamespace.MyClasName"<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        x:Class="Petzold.CompileXamlWindow.CompileXamlWindow">namespace Petzold.CompileXamlWindow{public partial class CompileXamlWindow : Window{	…}}
BAML (바멜)XAML의 바이너리 형태CompileXamlWindow.g.csXAML로부터 산출된 코드Lstbox와 elips가 선언InitializeComponent()XAML을 코드와 함께 컴파일했을 때만 가능public CompileXamlWindow(){InitializeComponent();	// XAML 엘리먼트 속성 설정, 이벤트 핸들러 연결…}void ButtonOnClick(object sender, RoutedEventArgsargs){Button btn = sender as Button;		// 생략가능…}
자신의 클래스를 XAML 내에서 사용다른 네임스페이스 선언반드시 소문자http: 와 유사사용하기 전에 선언src (소스코드)가 자주 쓰임UseCustomClass.xamlUseCustomClass.csColorGridBox가 상속받은 ListBox로 바꾸면 생략가능데이터 바인딩을 정의하면 SelectionChanged이벤트 핸들러를 완전히 XAML 파일 속으로 넣을 수 있음 (23장)xmlns:stuff=“clr-namespace:MyNamespace”<stuff:MyControl …>using Petzold.SelectColorFromGrid;…void ColorGridBoxOnSelectionChanged(object sender, SelectionChangedEventArgsargs){ColorGridBoxclrbox = args.Source as ColorGridBox;…}
XAML에서 사용자 정의 클래스 정의CenteredButton.xamlUseCustomXamlClass.xaml<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        x:Class="Petzold.UseCustomXamlClass.CenteredButton"HorizontalAlignment="Center"VerticalAlignment="Center"        Margin="12" /><Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:src="clr-namespace:Petzold.UseCustomXamlClass"         x:Class="Petzold.UseCustomXamlClass.UseCustomXamlClass"        Title = "Use Custom XAML Class">    <StackPanel Name="stack"><src:CenteredButton>Button A</src:CenteredButton>        <src:CenteredButton>Button B</src:CenteredButton>        <src:CenteredButton>Button C</src:CenteredButton>        <src:CenteredButton>Button D</src:CenteredButton>        <src:CenteredButton>Button E</src:CenteredButton>    </StackPanel></Window>
Cont’dUseCustomXamlClass.cspublic UseCustomXamlClass(){InitializeComponent();for (inti = 0; i < 5; i++){CenteredButtonbtn = new CenteredButton();btn.Content = "Button No. " + (i + 1);stack.Children.Add(btn);}}
명확한 Main이 사라지는 현상MyApplication.xamlApplicationDefinition으로 빌드 작업 설정StartupUri는 Main 함수에서 호출되는 Run 메소드를 대체, 초기 Window 객체 띄움MyApplication.csMyApplication.g.cs파일에서는 Main 메소드 있음삭제가능<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             x:Class="Petzold.IncludeApplicationDefinition.MyApplication"StartupUri="MyWindow.xaml" />namespace Petzold.IncludeApplicationDefinition{    public partial class MyApplication : Application    {    }}
코드가 없는 프로젝트XAML 속에 데이터 바인딩을 가지고 있는 경우XAML 애니메이션을 사용하는 경우XamlOnlyApp.xaml컴파일 시 클래스 자동 생성XamlOnlyWindow.xamlBAML	실제 구조는 코드를 가진 프로젝트와 유사<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"StartupUri="XamlOnlyWindow.xaml" /> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        Title="Compile XAML Only"SizeToContent="WidthAndHeight"ResizeMode="CanMinimize">    <StackPanel>	…    </StackPanel></Window>
XAML 파일 속에 C# 코드 넣기앞의 CompileXamlOnly프로젝트와 유사EmbeddedCodeWindow.xaml필드 정의는 불가능using등의 문제 해결 위해 System.Reflection네임스페이스의 클래스 숙지<Window><StackPanel>…<x:Code><![CDATA[	…        void ListBoxOnSelection(object sender, SelectionChangedEventArgsargs){            string strItem = lstbox.SelectedItem as string;System.Reflection.PropertyInfo prop = typeof(Brushes).GetProperty(strItem);elips.Fill = (Brush)prop.GetValue(null, null);}]]></x:Code></StackPanel></Window>
응용리소스에 이미지 파일 추가DesignXamlButtonWindow.xaml<ButtonHorizontalAlignment="Center“ VerticalAlignment="Center“  Margin="24"><StackPanel><Polyline Stroke="Black" Points="0 10,10 0,20 10,30 0,40 10,50 0,60 10,70 0,80 10,90 0,100 10" /><Image Margin="0,10,0,0" Source="BOOK06.ICO"  Stretch="None" /><LabelHorizontalAlignment="Center">                _Read Books!</Label><Polyline Stroke="Black" Points="0 0,10 10,20 0,30 10,40 0,50 10,60 0,70 10,80 0,90 10,100 0" /></StackPanel></Button>
20장 프로퍼티와 속성
동적 XAML ReaderXamlCruncher프로젝트XamlCruncherAssemblyInfo.cs프로그램 정보XamlCruncherSettings.cspublic Dock Orientation = Dock.Left;        // TextBox와 Frame 위치제어public intTabSpaces = 4;                   // 탭키를누를때 삽입할공백개수public string StartupDocument =             // 처음나오는 XAML을설정"<Button xmlns=\"http://schemas.microsoft.com/winfx" +                         "/2006/xaml/presentation\"\r\n" +            "        xmlns:x=\"http://schemas.microsoft.com/winfx" +                         "/2006/xaml\">\r\n" +            "    Hello, XAML!\r\n" +            "</Button>\n";// 생성자. 폰트지정public XamlCruncherSettings(){FontFamily = "Lucida Console";FontSize = 10 / 0.75;}
XamlCruncher.csXamlCruncher.csWindow의 컨텐트가 될 Grid를 생성Xaml이라는 최상위 메뉴와 하위 메뉴 생성// DockPanel을 찾은 후 그것에서 TextBox를 제거DockPaneldock = txtbox.Parentas DockPanel;dock.Children.Remove(txtbox);// Grid 생성, 3개의 열과 행Grid grid=new Grid();dock.Children.Add(grid);// Xaml을 최상위 메뉴로 삽입MenuItemitemXaml = new MenuItem();itemXaml.Header = "_Xaml";menu.Items.Insert(menu.Items.Count - 1, itemXaml);
Cont’dvoid Parse(){StringReaderstrreader = new StringReader(txtbox.Text);XmlTextReaderxmlreader = new XmlTextReader(strreader);try{object obj = XamlReader.Load(xmlreader); // 예외 상황 발생 시txtbox.Foreground = SystemColors.WindowTextBrush;	if (obj is Window){// Window 객체를 위해서는 F7키를 눌렀을 때 독립된 창을 띄워줌win = objas Window;statusParse.Content = "Press F7 to display Window";}	else{// Frame 컨트롤의 Content 프로퍼티에 설정win = null;frameParent.Content = obj;statusParse.Content = "OK";}}catch (Exception exc){	// TextBox의 텍스트 전체를 붉은색으로 표시하고 메시지를 상태표시줄에 표시txtbox.Foreground = Brushes.Red;statusParse.Content = exc.Message;}}
공백 개수 변경XamlTabSpaceDialog.xaml대화상자의 배치 정의XamlTabSpaceDialog.csXamlCruncher.csTab Space 메뉴 선택 시 위 대화상자 호출public intTabSpaces{set { txtbox.Text = value.ToString(); }get { return Int32.Parse(txtbox.Text);}}void TextBoxOnTextChanged(object sender,TextChangedEventArgsargs){intresult;btnOk.IsEnabled = (Int32.TryParse(txtbox.Text, out result) &&result > 0 && result < 11);}void OkOnClick(object sender, RoutedEventArgsargs){DialogResult = true;}
TextBox와 Frame의 위치 변경XamlOrientationMenuItem.cs
Star.xamlPoints 프로퍼티PointCollection타입연속적인 X와 Y 좌표를 포인트로 명세숫자는 공백이나 콤마로 구분 가능Fill 프로퍼티Brushes 클래스의 정적 멤버 사용16진법으로 RGB 색상 사용 가능알파 채널 적용 가능 (128)부동소수점으로 scRGB스킴으로 표현<Polygon xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         Points="144 48, 200 222, 53 114, 235 114, 88 222"         Fill="Red"          Stroke="Blue"StrokeThickness="5" />Fill=“FF0000”Fill=“#80FF0000”Fill=“sc#0.5,1,0,0”
LinearGradientBrush적어도 2개의 값과 그라디언트스탑 필요객체 엘리먼트(Polygon) & 프로퍼티 속성(Fill)자식 엘리먼트를 포함하는 문법으로 프로퍼티 명세 가능 (프로퍼티엘리먼트, 속성요소)<Polygon><Polygon.Fill>        Red    </Polygon.Fill></Polygon><Polygon.Fill>    <Brush>        Red    </Brush></Polygon.Fill>(Brush 타입의 Fill 프로퍼티 참조)<Polygon.Fill>    <SolidColorBrush>        Red    </ SolidColorBrush></Polygon.Fill>(Brush는 SolidColorBrush타입의 객체로 변환가능)<Polygon.Fill>    <SolidColorBrush Color=“Red”>    </ SolidColorBrush></Polygon.Fill>(SolidColorBrush는 객체이므로 프로퍼티 가질 수 있음)<!-- 잘못된 문법-><Polygon.FillAttr=“Whatever”>    …</Polygon.Fill>(프로퍼티는프로퍼티 가질 수 없음)
Cont’d<Polygon xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         Points="144 48, 200 222, 53 114, 235 114, 88 222"         Stroke="Blue"StrokeThickness="5">    <Polygon.Fill>        <RadialGradientBrush>            <GradientStop Offset="0" Color="Blue" />            <GradientStop Offset="1" Color="Red" />        </RadialGradientBrush>    </Polygon.Fill></Polygon>
윈도우 컨텐트프로퍼티DockPanelGridStackPanel
RoutedEvent클래스와 이벤트 이름으로 속성으로 사용함으로써 이벤트 핸들러 설정 가능<TextBlock.ContextMenu>	<ContextMenuMenuItem.Click="MenuItemOnClick">	<MenuItem Header="Red" /><MenuItem Header="Orange" /><MenuItem Header="Yellow" /><MenuItem Header="Green" /><MenuItem Header="Blue" /><MenuItem Header="Indigo" /><MenuItem Header="Violet" /></ContextMenu></TextBlock.ContextMenu>
Thank youQ&A

Introduction To Xaml

  • 1.
    Introduction to XAMLKim,Hyunyoung (young_kim@kaist.ac.kr)Digital Media Lab.2010-07-07
  • 2.
  • 3.
  • 4.
    XAML [zæ:mɛl]WPF (WindowPresentation Foundation)인터페이스와 비즈니스 로직을 분명히 구분응용 프로그램 서비스의 호스트를 통일: 인터페이스, 애니메이션, 3D, 오디오 등XML (Extensible Markup Language)XAML (Extensible Application Markup Language)마이크로소프트에서 구조값과 객체를 초기화하는데 사용하기 위해 만든 선언형XML 기반 언어WPF 의 사용자 인터페이스를 위한 언어런타임 속성편집 도구의 자유: 비주얼 스튜디오, 익스프레션블렌드, 메모장의사소통: 개발자와 디자이너 간에 콘텐츠를 자유롭게 공유하고 편집 가능C# 코드로 표현 가능System.Windows.Controls<Button Foreground=“Yellow” FontSize=“24pt”> Hello, XAML!</Button>Button btn = new Button();btn.Foreground = Brushes.Yellow;btn.FontSize = 32; // 장치 독립적 단위btn.Content = “Hello, XAML!”
  • 5.
    Stand Alone XAML두문서에 같은 엘리먼트 이름을서로 다른 목적으로 사용하는 경우WPF 프로그래머의 XAML 문서 & 셔츠 버튼 제조업자의 XML 문서 xmlns: XML 네임스페이스 속성엘리먼트와 자식 엘리먼트에게 적용유일하고 영속적,URL을 사용하는 것이 일반적예제XamlStackPanel.xamlPresentationHost.exe인터넷 익스플로러에 의해 호스팅될 수 있는 Page타입의 객체를 생성로드된XAML을 실제 StackPanel, Button등객체로 변환한 후 이 객체를 Page의 컨텐트 프로퍼티에 저장<Button Foreground=“Yellow” FontSize=“24pt”> Hello, XAML!</Button>http://schemas.microsoft.com/winfx/2006/xaml/presentation
  • 6.
    페이지 속성 변경예제XamlPage.xamlPage를 루트 엘리먼트로 생성하고 WindowTitle프로퍼티에 원하는 텍스트를 설정StackPanel을 Page의 자식으로 생성Window를 루트 엘리먼트로 한 스탠드얼론XAML은 불가능PresentationHost.exe는 스탠드얼론 XAML 파일의 루트 엘리먼트를 어떤 것의 자식으로 만듦Window객체는 그 어떤 것의 자식도 될 수 없음루트 엘리먼트는Window를 제외하고 FrameworkElement를 상속받는 것이면 어떤 것도 가능
  • 7.
    XamlReader.LoadXamlReader.Load메소드System.Windows.Markup네임스페이스XAML을 파싱해 초기화된객체로 전환XamlWriter.Save는 객체로부터 XAML을 생성Stream 객체나 XmlReader객체를 받음string strXaml ="<Button xmlns='http://schemas.microsoft.com/winfx/2006/" +" xaml/presentation'" +" Foreground='LightSeaGreen' FontSize='24pt'>" +"Click me!" +"</Button>";StringReaderstrreader = new StringReader(strXaml);XmlTextReaderxmlreader = new XmlTextReader(strreader);object obj = XamlReader.Load(xmlreader);
  • 8.
    XAML을 리소스로 사용하기LoadXamlResource.xmlButton객체에Name속성 포함LoadXamlResource.csStream 객체가 XamlReader.Load의 인자가 되어 반환되는 객체(StackPanel)를 Window의Content프로퍼티에 할당일단 객체가 XAML로부터 변환되어 창의 비주얼트리의 일부가 되면 FindName메소드를 사용해서 엘리먼트트리상에서 특정한 이름으로 찾는 것이 가능실행 시에 로드한XAML에게 이벤트 핸들러를 연결할 수 있는 가장 간단한 방법<Button Name="MyButton" HorizontalAlignment="Center" Margin="24">Hello, XAML!</Button>Uri uri = new Uri("pack://application:,,,/LoadXamlResource.xml");Stream stream = Application.GetResourceStream(uri).Stream;FrameworkElement el = XamlReader.Load(stream) as FrameworkElement;Content = el;Button btn = el.FindName("MyButton") as Button;if (btn != null)btn.Click += ButtonOnClick;
  • 9.
    Window가 루트인 XamlLoadXamlWindow.xmlLoadXamlWindow.csPresentationHost.exe는XAML을 어떤 것의 자식으로 변환여기서는 XAML 리소스가 Window임을 인식, Window를 상속받거나 Window자체를 직접 생성하지 않음버튼 클릭 이벤트 핸들러를비주얼 트리 속에서 찾아 연결하지 않고 Window의 AddHandler를 호출해 연결Main메소드는Application의 Run메소드에Window객체를 인자로 전달<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="Load Xaml Window"SizeToContent="WidthAndHeight"ResizeMode="CanMinimize">Uri uri = new Uri("pack://application:,,,/LoadXamlWindow.xml");Stream stream = Application.GetResourceStream(uri).Stream;Window win = XamlReader.Load(stream) as Window;win.AddHandler(Button.ClickEvent, new RoutedEventHandler(ButtonOnClick));app.Run(win);
  • 10.
    XAML을 C#에서 로드하기파일명은XmlTextReader생성자로 바로 전달객체가 Window이면 모달리스 대화상자처럼 보임XmlTextReaderxmlreader = new XmlTextReader(dlg.FileName);object obj = XamlReader.Load(xmlreader);if (obj is Window){Window win = obj as Window;win.Owner = this;win.Show();}Elseframe.Content = obj;
  • 11.
    XAML실제 애플리케이션에서는 XAML을소스 코드와 함께 컴파일 하는 것이 보편적, 효율적XAML 안에 이벤트 핸들러 이름을 직접 명시가능지금까지 본 XAMLWPF의 클래스와 프로퍼티만을 사용그러나 XAML은 WPF만을 위한 마크업 언어는 아님 (예: Windows Workflow Foundation, WPF)http://schemas.microsoft.com/winfx/2006/xaml: XAML 명세WPF에서 사용XAML 고유 엘리먼트와 속성을 위한 네임스페이스는 관례적으로 접두어x와 함께 선언고유 엘리먼트와 속성이 많지 않아 WPF 관련 네임스페이스가 기본xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:x=http://schemas.microsoft.com/winfx/2006/xaml/presentation
  • 12.
    Class속성Class 속성XAML 파일의루트 엘리먼트XAML이 프로젝트 일부로 컴파일될 때만 사용 가능CompileXamlWindow.xamlXAML 과 비하인드 코드는 하나의 클래스x:Class="MyNamespace.MyClasName"<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Petzold.CompileXamlWindow.CompileXamlWindow">namespace Petzold.CompileXamlWindow{public partial class CompileXamlWindow : Window{ …}}
  • 13.
    BAML (바멜)XAML의 바이너리형태CompileXamlWindow.g.csXAML로부터 산출된 코드Lstbox와 elips가 선언InitializeComponent()XAML을 코드와 함께 컴파일했을 때만 가능public CompileXamlWindow(){InitializeComponent(); // XAML 엘리먼트 속성 설정, 이벤트 핸들러 연결…}void ButtonOnClick(object sender, RoutedEventArgsargs){Button btn = sender as Button; // 생략가능…}
  • 14.
    자신의 클래스를 XAML내에서 사용다른 네임스페이스 선언반드시 소문자http: 와 유사사용하기 전에 선언src (소스코드)가 자주 쓰임UseCustomClass.xamlUseCustomClass.csColorGridBox가 상속받은 ListBox로 바꾸면 생략가능데이터 바인딩을 정의하면 SelectionChanged이벤트 핸들러를 완전히 XAML 파일 속으로 넣을 수 있음 (23장)xmlns:stuff=“clr-namespace:MyNamespace”<stuff:MyControl …>using Petzold.SelectColorFromGrid;…void ColorGridBoxOnSelectionChanged(object sender, SelectionChangedEventArgsargs){ColorGridBoxclrbox = args.Source as ColorGridBox;…}
  • 15.
    XAML에서 사용자 정의클래스 정의CenteredButton.xamlUseCustomXamlClass.xaml<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Petzold.UseCustomXamlClass.CenteredButton"HorizontalAlignment="Center"VerticalAlignment="Center" Margin="12" /><Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:src="clr-namespace:Petzold.UseCustomXamlClass" x:Class="Petzold.UseCustomXamlClass.UseCustomXamlClass" Title = "Use Custom XAML Class"> <StackPanel Name="stack"><src:CenteredButton>Button A</src:CenteredButton> <src:CenteredButton>Button B</src:CenteredButton> <src:CenteredButton>Button C</src:CenteredButton> <src:CenteredButton>Button D</src:CenteredButton> <src:CenteredButton>Button E</src:CenteredButton> </StackPanel></Window>
  • 16.
    Cont’dUseCustomXamlClass.cspublic UseCustomXamlClass(){InitializeComponent();for (inti= 0; i < 5; i++){CenteredButtonbtn = new CenteredButton();btn.Content = "Button No. " + (i + 1);stack.Children.Add(btn);}}
  • 17.
    명확한 Main이 사라지는현상MyApplication.xamlApplicationDefinition으로 빌드 작업 설정StartupUri는 Main 함수에서 호출되는 Run 메소드를 대체, 초기 Window 객체 띄움MyApplication.csMyApplication.g.cs파일에서는 Main 메소드 있음삭제가능<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Petzold.IncludeApplicationDefinition.MyApplication"StartupUri="MyWindow.xaml" />namespace Petzold.IncludeApplicationDefinition{ public partial class MyApplication : Application { }}
  • 18.
    코드가 없는 프로젝트XAML속에 데이터 바인딩을 가지고 있는 경우XAML 애니메이션을 사용하는 경우XamlOnlyApp.xaml컴파일 시 클래스 자동 생성XamlOnlyWindow.xamlBAML 실제 구조는 코드를 가진 프로젝트와 유사<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"StartupUri="XamlOnlyWindow.xaml" /> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="Compile XAML Only"SizeToContent="WidthAndHeight"ResizeMode="CanMinimize"> <StackPanel> … </StackPanel></Window>
  • 19.
    XAML 파일 속에C# 코드 넣기앞의 CompileXamlOnly프로젝트와 유사EmbeddedCodeWindow.xaml필드 정의는 불가능using등의 문제 해결 위해 System.Reflection네임스페이스의 클래스 숙지<Window><StackPanel>…<x:Code><![CDATA[ … void ListBoxOnSelection(object sender, SelectionChangedEventArgsargs){ string strItem = lstbox.SelectedItem as string;System.Reflection.PropertyInfo prop = typeof(Brushes).GetProperty(strItem);elips.Fill = (Brush)prop.GetValue(null, null);}]]></x:Code></StackPanel></Window>
  • 20.
    응용리소스에 이미지 파일추가DesignXamlButtonWindow.xaml<ButtonHorizontalAlignment="Center“ VerticalAlignment="Center“ Margin="24"><StackPanel><Polyline Stroke="Black" Points="0 10,10 0,20 10,30 0,40 10,50 0,60 10,70 0,80 10,90 0,100 10" /><Image Margin="0,10,0,0" Source="BOOK06.ICO" Stretch="None" /><LabelHorizontalAlignment="Center"> _Read Books!</Label><Polyline Stroke="Black" Points="0 0,10 10,20 0,30 10,40 0,50 10,60 0,70 10,80 0,90 10,100 0" /></StackPanel></Button>
  • 21.
  • 22.
    동적 XAML ReaderXamlCruncher프로젝트XamlCruncherAssemblyInfo.cs프로그램정보XamlCruncherSettings.cspublic Dock Orientation = Dock.Left; // TextBox와 Frame 위치제어public intTabSpaces = 4; // 탭키를누를때 삽입할공백개수public string StartupDocument = // 처음나오는 XAML을설정"<Button xmlns=\"http://schemas.microsoft.com/winfx" + "/2006/xaml/presentation\"\r\n" + " xmlns:x=\"http://schemas.microsoft.com/winfx" + "/2006/xaml\">\r\n" + " Hello, XAML!\r\n" + "</Button>\n";// 생성자. 폰트지정public XamlCruncherSettings(){FontFamily = "Lucida Console";FontSize = 10 / 0.75;}
  • 23.
    XamlCruncher.csXamlCruncher.csWindow의 컨텐트가 될Grid를 생성Xaml이라는 최상위 메뉴와 하위 메뉴 생성// DockPanel을 찾은 후 그것에서 TextBox를 제거DockPaneldock = txtbox.Parentas DockPanel;dock.Children.Remove(txtbox);// Grid 생성, 3개의 열과 행Grid grid=new Grid();dock.Children.Add(grid);// Xaml을 최상위 메뉴로 삽입MenuItemitemXaml = new MenuItem();itemXaml.Header = "_Xaml";menu.Items.Insert(menu.Items.Count - 1, itemXaml);
  • 24.
    Cont’dvoid Parse(){StringReaderstrreader =new StringReader(txtbox.Text);XmlTextReaderxmlreader = new XmlTextReader(strreader);try{object obj = XamlReader.Load(xmlreader); // 예외 상황 발생 시txtbox.Foreground = SystemColors.WindowTextBrush; if (obj is Window){// Window 객체를 위해서는 F7키를 눌렀을 때 독립된 창을 띄워줌win = objas Window;statusParse.Content = "Press F7 to display Window";} else{// Frame 컨트롤의 Content 프로퍼티에 설정win = null;frameParent.Content = obj;statusParse.Content = "OK";}}catch (Exception exc){ // TextBox의 텍스트 전체를 붉은색으로 표시하고 메시지를 상태표시줄에 표시txtbox.Foreground = Brushes.Red;statusParse.Content = exc.Message;}}
  • 25.
    공백 개수 변경XamlTabSpaceDialog.xaml대화상자의배치 정의XamlTabSpaceDialog.csXamlCruncher.csTab Space 메뉴 선택 시 위 대화상자 호출public intTabSpaces{set { txtbox.Text = value.ToString(); }get { return Int32.Parse(txtbox.Text);}}void TextBoxOnTextChanged(object sender,TextChangedEventArgsargs){intresult;btnOk.IsEnabled = (Int32.TryParse(txtbox.Text, out result) &&result > 0 && result < 11);}void OkOnClick(object sender, RoutedEventArgsargs){DialogResult = true;}
  • 26.
    TextBox와 Frame의 위치변경XamlOrientationMenuItem.cs
  • 27.
    Star.xamlPoints 프로퍼티PointCollection타입연속적인 X와Y 좌표를 포인트로 명세숫자는 공백이나 콤마로 구분 가능Fill 프로퍼티Brushes 클래스의 정적 멤버 사용16진법으로 RGB 색상 사용 가능알파 채널 적용 가능 (128)부동소수점으로 scRGB스킴으로 표현<Polygon xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Points="144 48, 200 222, 53 114, 235 114, 88 222" Fill="Red" Stroke="Blue"StrokeThickness="5" />Fill=“FF0000”Fill=“#80FF0000”Fill=“sc#0.5,1,0,0”
  • 28.
    LinearGradientBrush적어도 2개의 값과그라디언트스탑 필요객체 엘리먼트(Polygon) & 프로퍼티 속성(Fill)자식 엘리먼트를 포함하는 문법으로 프로퍼티 명세 가능 (프로퍼티엘리먼트, 속성요소)<Polygon><Polygon.Fill> Red </Polygon.Fill></Polygon><Polygon.Fill> <Brush> Red </Brush></Polygon.Fill>(Brush 타입의 Fill 프로퍼티 참조)<Polygon.Fill> <SolidColorBrush> Red </ SolidColorBrush></Polygon.Fill>(Brush는 SolidColorBrush타입의 객체로 변환가능)<Polygon.Fill> <SolidColorBrush Color=“Red”> </ SolidColorBrush></Polygon.Fill>(SolidColorBrush는 객체이므로 프로퍼티 가질 수 있음)<!-- 잘못된 문법-><Polygon.FillAttr=“Whatever”> …</Polygon.Fill>(프로퍼티는프로퍼티 가질 수 없음)
  • 29.
    Cont’d<Polygon xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Points="144 48, 200 222, 53 114, 235 114, 88 222" Stroke="Blue"StrokeThickness="5"> <Polygon.Fill> <RadialGradientBrush> <GradientStop Offset="0" Color="Blue" /> <GradientStop Offset="1" Color="Red" /> </RadialGradientBrush> </Polygon.Fill></Polygon>
  • 30.
  • 31.
    RoutedEvent클래스와 이벤트 이름으로속성으로 사용함으로써 이벤트 핸들러 설정 가능<TextBlock.ContextMenu> <ContextMenuMenuItem.Click="MenuItemOnClick"> <MenuItem Header="Red" /><MenuItem Header="Orange" /><MenuItem Header="Yellow" /><MenuItem Header="Green" /><MenuItem Header="Blue" /><MenuItem Header="Indigo" /><MenuItem Header="Violet" /></ContextMenu></TextBlock.ContextMenu>
  • 32.