XAML 개요

업데이트: 2007년 11월

이 항목에서는 XAML(Extensible Application Markup Language) 언어의 특징을 설명하고 XAML을 사용하여 WPF(Windows Presentation Foundation) 응용 프로그램을 작성하는 방법을 보여 줍니다. 이 항목에서는 특히 WPF(Windows Presentation Foundation)에서 구현하는 XAML에 대해 설명합니다. XAML 자체는 WPF(Windows Presentation Foundation)보다 넓은 언어 개념입니다.

이 항목에는 다음 단원이 포함되어 있습니다.

  • 흐름 제어를 지원하는 선언적 언어
  • XAML 개체 요소
  • 속성 설정
  • 참조 값 및 태그 확장
  • Typeconverter 지원 특성 값
  • 컬렉션 형식 및 XAML 컬렉션 속성
  • XAML 콘텐츠 속성
  • XAML의 대/소문자 및 공백
  • XAML 구문 추가 정보
  • XAML 루트 요소 및 XML 네임스페이스
  • 이벤트 및 XAML 코드 숨김
  • x:Name
  • 연결된 속성 및 연결된 이벤트
  • 기본 클래스 및 XAML
  • XAML 보안
  • 코드에서 XAML 로드
  • 새로운 기능
  • 관련 항목

흐름 제어를 지원하는 선언적 언어

XAML은 .NET Framework 프로그래밍 모델에 대한 UI의 작성을 단순화합니다. 선언적 XAML 태그에 시각적 UI 요소를 만든 다음 코드 숨김 파일을 사용하여 UI 정의를 런타임 논리와 분리할 수 있습니다. 이 정의는 partial 클래스 정의를 통해 태그에 연결됩니다. XML은 자체적으로 선언적이며 흐름 제어를 위한 모델을 실제로 제안하지 않기 때문에 XAML에서 태그와 코드를 혼합할 수 있는 기능은 매우 중요합니다. 특히, 웹 디자인 및 기술에 대한 배경 지식을 가진 사용자의 입장에서 볼 때 XML 기반 선언적 언어는 프로토타입에서 프로덕션에 이르기까지의 인터페이스를 만들 때 매우 편리합니다. 대부분의 다른 태그 언어와 달리 XAML은 관리되는 개체의 인스턴스화를 직접 나타냅니다. 이러한 일반적인 디자인 원칙은 XAML에서 작성된 개체에 대한 코드 및 디버깅 액세스를 간편하게 합니다.

XAML 파일은 일반적으로 확장명이 .xaml인 XML 파일입니다.

다음 XAML 예제에서는 UI의 일부로 단추를 만들 때 필요한 태그의 수가 얼마나 적은지 보여 줍니다. 이 단추의 기본 시각적 표현은 테마 스타일을 통해 구현되고 기본 동작은 클래스 디자인을 통해 구현됩니다.

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

XAML 개체 요소

XAML에는 개체 요소를 클래스 또는 구조체로, 특성을 속성이나 이벤트로, XML 네임스페이스를 CLR 네임스페이스로 매핑하는 규칙 집합이 있습니다. XAML 요소는 참조된 어셈블리에 정의된 대로 Microsoft .NET 형식에 매핑되며 특성은 해당 형식의 멤버로 매핑됩니다.

앞의 예제에서는 <StackPanel>(닫는 태그 포함) 및 <Button/>(여기에도 몇 개의 특성이 있으며 이후 단원에서 설명)이라는 두 개체 요소를 지정합니다. 문자열 StackPanel과 Button은 각각 WPF에 정의된 클래스 이름으로 매핑되며 WPF 어셈블리의 일부입니다. 개체 요소 태그를 지정할 때는 XAML 페이지가 로드될 때 명명된 클래스의 새 인스턴스를 만들기 위해 XAML이 처리할 명령을 만듭니다. 각 인스턴스는 기본 클래스 또는 구조체의 기본 생성자를 호출하고 그 결과를 저장하여 만들어집니다. XAML에서 개체 요소로 사용할 수 있으려면 클래스 또는 구조체가 public 기본(매개 변수 없는) 생성자를 노출해야 합니다.

속성 설정

XAML의 속성은 다양한 구문을 사용하여 개체 요소에 속성을 설정하여 설정합니다. 특정 속성에 사용할 수 있는 구문은 설정하는 속성의 특성에 따라 다릅니다.

속성 값을 설정하여 개체 요소에 기능이나 특성을 추가할 수 있습니다. 개체 요소에 대한 기본 개체 인스턴스의 초기 상태는 기본 생성자 동작을 기반으로 합니다. 일반적으로 응용 프로그램에서는 특정 개체의 완전한 기본 인스턴스가 아닌 다른 것을 사용합니다.

특성 구문

XAML에서 속성은 특성으로 노출될 수도 있습니다. 특성 구문은 가장 효율적인 속성 설정 구문이며 과거에 태그 언어를 사용한 적이 있는 개발자에게 가장 직관적인 구문입니다. 예를 들어, 다음 태그는 빨간색 텍스트와 파란색 배경이 있으며 Content로 지정된 텍스트를 표시하는 단추를 만듭니다.

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

속성 요소 구문

개체 요소의 일부 속성의 경우에는 속성 값을 제공하기 위해 필요한 개체나 정보를 간단한 문자열로 적절하게 표현할 수 없기 때문에 특성 구문을 사용할 수 없습니다. 이러한 경우에는 속성 요소 구문이라고 하는 다른 구문을 사용할 수 있습니다. 속성 요소 구문은 포함 요소의 참조된 속성을 태그의 콘텐츠와 함께 설정합니다. 일반적으로 콘텐츠는 속성이 해당 속성의 값으로 사용하는 형식의 개체이며 대개 다른 개체 요소로 지정된 값 설정 인스턴스가 사용됩니다. 속성 요소 자체의 구문은 <TypeName.Property>입니다. 콘텐츠를 지정한 뒤에는 </TypeName.Property> 구문을 사용하는 다른 요소와 마찬가지로 닫는 태그로 속성 요소를 닫아야 합니다. 특성과 속성 요소 구문이 모두 지원되는 속성의 경우 두 구문의 결과는 일반적으로 동일하지만, 구문에 따라 공백 처리와 같은 세세한 부분은 조금 다를 수 있습니다. 특성 구문이 지원되는 경우에는 특성 구문을 사용하는 것이 일반적으로 더 편리하며 태그를 더 간결하게 만들 수 있지만 이는 기술적 제한이 아니라 스타일의 문제일 뿐입니다. 다음 예제에서는 앞의 특성 구문 예제에서와 같이 동일한 속성을 설정하는 것을 보여 주지만 이번에는 Button의 모든 속성에 대해 속성 요소 구문을 사용합니다.

<Button>
  <Button.Background>
    <SolidColorBrush Color="Blue"/>
  </Button.Background>
  <Button.Foreground>
    <SolidColorBrush Color="Red"/>
  </Button.Foreground>
  <Button.Content>
    This is a button
  </Button.Content>
</Button>

XAML에 대한 속성 요소 구문은 태그에 대한 기본 XML 해석과 큰 차이를 나타냅니다. XML에서 <TypeName.Property>는 자식 요소 관계 및 TypeName 부모와 어떤 암시적 관계가 없는 다른 요소를 나타냅니다. XAML에서 <TypeName.Property>는 Property가 TypeName의 속성이고, 해당 속성 요소 콘텐츠에 의해 설정됨을 의미하며, 우연히 이름에 점이 비슷한 이름이지만 별개의 요소가 결코 아님을 의미합니다.

속성 및 클래스 상속

WPF 요소에서 XAML 특성으로 나타나는 속성은 대개 기본 클래스에서 상속됩니다. 예를 들어, 앞의 예제에서 클래스 정의, 리플렉션 결과 또는 문서를 확인하더라도 Background 속성은 Button 클래스에서 곧바로 선언된 속성이 아닙니다. Background는 기본 Control 클래스에서 상속되었습니다.

WPF XAML 요소의 클래스 상속 동작 또한 태그에 대한 기본 XML 해석과 큰 차이를 나타냅니다. 클래스 상속(특히 중간 기본 클래스가 추상인 경우)은 XAML 요소 및 해당 허용 가능한 특성 집합을 DTD 또는 XSD 형식과 같이 XML 프로그래밍에 일반적으로 사용되는 스키마 형식을 사용하여 정확하고 완전하게 표현하기 어렵게 하는 요인 중 하나입니다. 또한 XAML의 "X"는 "확장 가능(eXtensible)"을 나타냅니다. 확장성은 "WPF에 대한 XAML의 정의"로 내린 어떤 표현도 완전할 수 없음을 나타냅니다. 하지만 별도의 XML 네임스페이스 정의를 두면 이 문제를 해결하는 데 도움이 될 수 있습니다. 이 개념에 대해서는 이후 단원에서 설명합니다.

참조 값 및 태그 확장

태그 확장은 XAML 개념입니다. 특성 구문에서 중괄호({ 및 })는 태그 확장 사용을 나타냅니다. 이는 특성 값의 일반적인 처리를 리터럴 문자열 또는 직접 문자열 변환 가능 값으로 이스케이프하도록 XAML에 지시합니다.

속성이 참조 형식 값을 사용하는 경우 대개 이러한 속성에는 항상 새 인스턴스를 만드는 속성 요소 구문 또는 태그 확장을 통한 개체 참조가 필요합니다. 태그 확장 사용은 기존 인스턴스를 반환할 수 있기 때문에 더 다양하게 이용하거나 개체 오버헤드를 줄일 수 있습니다.

태그 확장을 사용하여 특성 값을 제공하는 경우 특성 값은 관련 태그 확장에 대한 지원 클래스 안에서 논리에 의해 제공되어야 합니다. WPF 응용 프로그램 프로그래밍에 가장 많이 사용되는 태그 확장은 데이터 바인딩 식에 사용되는 바인딩과 리소스 참조 StaticResourceDynamicResource입니다. 태그 확장을 사용하면 속성이 직접 개체 인스턴스화를 위한 특성 구문을 지원하지 않더라도 속성에 대한 참조 값을 제공하는 데 특성 구문을 사용할 수 있으며, XAML 속성을 속성 형식의 값으로 채워야 하는 요구 사항의 일반적인 동작을 연기하는 특정 동작을 사용할 수 있습니다.

예를 들어, 다음 예제에서는 특성 구문을 사용하여 Style 속성의 값을 설정합니다. Style 속성은 기본적으로 특성 구문 문자열 안에 지정할 수 없는 참조 형식인 Style 클래스의 인스턴스를 사용합니다. 하지만 이 경우 특성은 특정 태그 확장인 StaticResource를 참조합니다. 해당 태그 확장이 처리되면 이전에 리소스 사전에서 키가 지정된 리소스로 인스턴스화된 스타일에 대한 참조를 반환합니다.

<Page.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="Background" Value="Blue"/>
  </Style>


...


</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


  </Border>
</StackPanel>

리소스는 WPF 또는 XAML로 사용할 수 있게 되는 하나의 태그 확장 사용일 뿐입니다. 태그 확장의 참조 목록을 보려면 WPF 네임스페이스 XAML 확장 또는 XAML 네임스페이스(x:) 언어 기능을 참조하십시오. 태그 확장에 대한 자세한 내용은 태그 확장 및 XAML을 참조하십시오.

Typeconverter 지원 특성 값

특성 구문 단원에서는 특성 값을 문자열로 설정할 수 있어야 한다고 했습니다. 문자열이 다른 개체 형식 또는 기본 값으로 변환되는 방법에 대한 기본 처리는 String 형식 자체를 기반으로 합니다. 그러나 대부분의 WPF 형식 또는 해당 형식의 멤버는 더 복잡한 개체 형식의 인스턴스를 문자열을 통해 특성 값으로 지정할 수 있도록 기본 문자열 특성 처리 동작을 확장합니다. 코드 수준에서 이 처리는 문자열 특성 값을 처리하는 CLR 형식 변환기를 지정하는 방법으로 수행됩니다. 일반적으로 Margin과 같은 사각형 영역에 대한 측정치를 나타내는 데 사용하는 Thickness 구조체 형식은 XAML 태그에서 사용 편의성을 제공하기 위해 해당 형식을 사용하는 모든 속성에 대해 노출되는 특별한 typeconverter 지원 특성 구문을 가진 형식의 예입니다. 다음 예제에서는 typeconverter 지원 특성 구문을 사용하여 Margin의 값을 제공합니다.

<Button Margin="10,20,10,30" Content="Click me"/>

앞의 특성 구문 예제는 다음의 더 자세한 구문 예제와 동일합니다. 이 예제에서는 MarginThickness 개체 요소를 포함하는 속성 요소 구문을 통해 설정되며, Thickness의 네 가지 주요 속성이 새 인스턴스에서 특성으로 설정됩니다.

<Button Content="Click me">
  <Button.Margin>
    <Thickness Left="10" Top="20" Right="10" Bottom="30"/>
  </Button.Margin>
</Button>

typeconverter 지원 구문을 사용할지 더 자세한 해당 구문을 사용할지 여부는 일반적으로 코딩 스타일에 따른 선택 사항이지만 typeconverter 지원 구문을 사용하면 태그를 더 효율적으로 사용할 수 있습니다. 하지만 형식 개체 자체에 기본 생성자가 없기 때문에 typeconverter를 통해서만 해당 형식에 속성을 설정할 수 있는 몇 가지 개체가 있습니다. 이에 대한 예는 Cursor입니다.

typeconverter 지원 특성 구문이 지원되는 방법에 대한 자세한 내용은 TypeConverter 및 XAML을 참조하십시오.

컬렉션 형식 및 XAML 컬렉션 속성

XAML은 컬렉션 형식을 나타내는 개체 요소를 태그에서 의도적으로 생략할 수 있는 언어 기능을 지정합니다. XAML 프로세서가 컬렉션 형식을 사용하는 속성을 처리하는 경우, 해당 컬렉션에 대한 개체 요소가 태그에 없더라도 적절한 컬렉션 형식의 인스턴스가 암시적으로 만들어집니다. 컬렉션 형식의 SDK 참조 페이지에서 컬렉션에 대한 개체 요소가 의도적으로 생략된 이 구문은 XAML 구문 섹션에서 암시적인 컬렉션 구문으로 표시되기도 합니다.

암시적인 컬렉션 구문은 IListIDictionary를 구현하는 형식 또는 배열에 대해 사용할 수 있습니다.

암시적인 컬렉션 구문(호출은 하지 않음)의 예제는 XAML 리소스 예제에서 이미 살펴보았습니다.

<Page.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="Background" Value="Blue"/>
  </Style>


...


</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


  </Border>
</StackPanel>

루트 요소를 제외하고 다른 요소의 자식 요소로 중첩된 페이지의 모든 개체 요소는 실제로는 다음 경우 중 하나 또는 둘 모두에 해당하는 요소입니다. 첫 번째 경우는 부모 요소의 암시적 컬렉션 속성의 멤버이고, 두 번째 경우는 부모 요소에 대한 XAML 콘텐츠 속성의 값을 지정하는 요소입니다. XAML 콘텐츠 속성에 대해서는 이후 단원에서 설명합니다. 다시 말해 태그 페이지에서 부모 요소와 자식 요소의 관계는 실제로 루트의 단일 개체이며, 루트 아래의 모든 개체 요소는 부모의 속성 값을 제공하는 단일 인스턴스이거나 부모의 컬렉션 형식 속성 값인 컬렉션 내의 항목 중 하나입니다. 리소스 예제의 경우 Resources 속성은 ResourceDictionary 형식의 개체를 사용합니다. 다음 예제는 명시적으로 지정된 ResourceDictionary 요소에 대한 개체 요소가 있는 동일한 구문입니다.

<Page.Resources>
  <ResourceDictionary>
      <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
      <Style TargetType="Border" x:Key="PageBackground">
        <Setter Property="Background" Value="Blue"/>
      </Style>


...


  </ResourceDictionary>
</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


    </Border>
  </StackPanel>
</Page>

Resources 컬렉션은 일반적으로 사용되는 여러 WPF 프레임워크 수준 요소에 있는 컬렉션 속성의 한 예입니다. XAML에서 이 속성을 설정하려면 속성 요소 구문이 필요합니다. 속성 요소 내에 포함된 각 개체 요소는 컬렉션의 항목(IDictionary 구현)이 됩니다. 컬렉션 형식 자체에는 일반적으로 속성이나 항목을 포함하는 인덱서가 있지만 해당 속성은 완전히 암시적이므로 태그에서 지정할 수 없습니다. ResourceDictionary의 경우 이 속성은 Item 인덱서입니다.

전체 리소스 사전 사용 예제는 방법: 리소스 정의 및 참조를 참조하십시오.

XAML 콘텐츠 속성

XAML은 XAML 개체 요소로 사용할 수 있는 모든 클래스가 클래스의 인스턴스에 대한 XAML 콘텐츠 속성이 되도록 속성 중 정확하게 하나를 지정할 수 있는 언어 기능입니다. XAML 콘텐츠 속성이 있는 개체 요소를 XAML 프로세서가 처리할 때 해당 개체 요소의 모든 XML 자식 요소는 해당 콘텐츠 속성을 나타내는 암시적 속성 요소 태그 안에 포함된 것처럼 처리됩니다. 태그 안에서 XAML 콘텐츠 속성에 대한 속성 요소 구문을 생략할 수 없습니다. 태그에서 지정하는 모든 자식 요소는 XAML 콘텐츠 속성의 값이 됩니다.

XAML 콘텐츠 속성(호출은 하지 않음)의 예제는 이 항목의 첫 번째 예제에서 이미 보았습니다.

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

여기서 ButtonStackPanel의 자식 요소입니다. 이는 두 가지 서로 다른 이유로 두 태그를 생략하는 효율적이며 직관적인 태그입니다.

  • 생략된 StackPanel.Children 속성 요소: StackPanelPanel에서 파생됩니다. PanelPanel.Children을 XAML 콘텐츠 속성으로 정의합니다. 따라서 Panel의 모든 파생 클래스는 해당 XAML 콘텐츠 속성을 가지며 Panel.Children에 대한 속성 요소는 생략할 수 있습니다.

  • 생략된 UIElementCollection 개체 요소: Panel.Children 속성은 IList를 구현하는 UIElementCollection 형식을 사용합니다. 따라서 컬렉션에 대한 XAML 정의 규칙에 기반하여 UIElementCollection 개체 요소 태그를 생략할 수 있습니다. 이 경우 UIElementCollection은 실제로 개체 요소로 인스턴스화할 수 없습니다. 해당 컬렉션 개체를 명시적으로 선언할 수도 없습니다. 이는 UIElementCollection이 기본 생성자를 노출하지 않기 때문입니다. 다른 몇 가지 WPF 컬렉션 형식도 개체 요소 사용을 위한 생성자를 노출하지 않으며 그 이유는 XAML 컬렉션 구문 처리에서 이러한 생성자가 여전히 XAML에서 암시적으로 작동하는 것을 허용하기 때문입니다. 이런 이유로 예제에서 UIElementCollection 개체 요소가 주석 처리되어 있습니다. 주석 처리를 제거하면 예제가 컴파일되지 않습니다.

<StackPanel>
  <StackPanel.Children>
    <!--<UIElementCollection>-->
    <Button>
      <Button.Content>
        Click Me
      </Button.Content>
    </Button>
    <!--</UIElementCollection>-->
  </StackPanel.Children>
</StackPanel>

내부 텍스트 및 XAML 콘텐츠 속성

StackPanel / Button 예제에는 또 다른 변형도 있습니다.

<StackPanel>
  <Button>Click Me</Button>
</StackPanel>

Button에 대한 표시 텍스트를 지정하는 방법이 어떻게 바뀌는지 주의하여 살펴보십시오. 이전에는 Content 속성을 특성 구문에서 지정했습니다. 이번에는 표시 문자열이 Button 개체 요소 내의 내부 텍스트입니다. 이 구문은 ContentButton 기본 클래스 ContentControl의 XAML 콘텐츠 속성이기 때문에 작동합니다. 요소 안의 문자열은 ObjectContent 속성의 속성 형식을 기반으로 평가됩니다. Object는 문자열 형식 변환을 시도하지 않으므로 Content 속성의 값은 리터럴 문자열 값이 됩니다. 또는 Button 안의 콘텐츠는 모든 단일 Object일 수 있습니다. 일반적으로 Button과 같은 컨트롤은 클래스에 대한 XAML 콘텐츠 속성을 정의하므로 XAML 콘텐츠 속성을 UI 및 표시 텍스트, 컨트롤 합성 또는 둘 모두에 사용할 수 있습니다.

문자열을 요소 안에 콘텐츠로 배치하여 다른 일반적인 태그 언어와 비슷한 태그를 만드는 기능은 유동 문서 모델(자세한 내용은 Windows Presentation Foundation의 문서 참조) 및 지역화(Windows Presentation Foundation 전역화 참조)에 특히 중요합니다.

연속적이어야 하는 XAML 콘텐츠 속성 값

XAML 콘텐츠 속성의 값은 해당 개체 요소의 다른 모든 속성 요소의 맨 앞 또는 맨 뒤에 지정해야 합니다. XAML 콘텐츠 속성의 값이 문자열로 지정되거나 하나 이상의 개체로 지정되는 경우 모두에 해당합니다. 예를 들어, 다음 태그는 컴파일되지 않습니다.

<Button>I am a 
  <Button.Background>Blue</Button.Background>
  blue button</Button>

이 구문이 콘텐츠 속성에 대한 속성 요소 구문을 사용한 명시적 구문이면 콘텐츠 속성이 두 번 설정되기 때문에 이 구문은 올바르지 않습니다.

<Button>
  <Button.Content>I am a </Button.Content>
  <Button.Background>Blue</Button.Background>
  <Button.Content> blue button</Button.Content>
</Button>

마찬가지로 콘텐츠 속성이 컬렉션일 때 자식 요소가 속성 요소와 함께 분산된 경우도 올바르지 않은 예입니다.

<StackPanel>
  <Button>This example</Button>
  <StackPanel.Resources>
    <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
  </StackPanel.Resources>
  <Button>... is illegal XAML</Button>
</StackPanel>

콘텐츠 모델

클래스는 구문의 측면에서 XAML 요소로 사용되는 것을 지원할 수 있지만 해당 요소는 전체 콘텐츠 모델 또는 요소 트리의 필요한 위치에 배치된 경우에만 응용 프로그램이나 페이지에서 제대로 동작합니다. 예를 들어, MenuItem은 일반적으로 Menu와 같은 MenuBase 파생 클래스의 자식으로 배치해야 합니다. 특정 요소의 콘텐츠 모델은 컨트롤 및 XAML 요소로 사용할 수 있는 기타 WPF 클래스의 클래스 페이지에서 설명의 일부로 문서화됩니다. 더 복잡한 콘텐츠 모델을 사용하는 일부 컨트롤의 경우 콘텐츠 모델은 별도의 개념 항목으로 문서화됩니다. 콘텐츠 모델을 참조하십시오.

XAML의 대/소문자 및 공백

XAML은 대/소문자를 구분합니다. 개체 요소, 속성 요소 및 특성 이름은 모두 어셈블리의 기본 형식 또는 형식 멤버의 이름과 비교하여 적절한 대/소문자를 사용하여 지정해야 합니다. 특성 값의 경우 대/소문자가 항상 구분되는 것은 아닙니다. 값의 대/소문자 구분은 값 또는 속성 값 형식을 사용하는 속성과 연결된 형식 변환기의 동작에 따라 다릅니다. 예를 들어, Boolean 형식을 사용하는 속성은 true 또는 True를 같은 값으로 취급할 수 있지만 이는 Boolean에 대한 기본 문자열 형식 변환에서 이를 이미 허용했기 때문입니다.

XAML 프로세서 및 serializer는 의미 없는 공백은 모두 무시하거나 삭제하고 의미 있는 공백은 모두 정규화합니다. 이 동작은 일반적으로 XAML 콘텐츠 속성 안에서 문자열을 지정할 때만 영향을 줍니다. 간단히 말해 XAML은 공백, 줄 바꿈 및 탭 문자가 연속되는 문자열의 끝에 있는 경우 이를 공백으로 변환한 다음 하나의 공백을 유지합니다. XAML 공백 처리에 대해서는 이 항목에서 자세히 다루지 않습니다. 자세한 내용은 XAML의 공백 처리를 참조하십시오.

XAML 구문 추가 정보

암시적 컬렉션 구문 및 XAML 콘텐츠 속성은 모두 특정 유추된 태그의 생략을 가능하게 하는 XAML 언어의 기능입니다. 이 기능의 목적은 태그를 작성하거나 검사할 때 페이지에 있는 요소의 부모-자식 관계를 더 명확하게 하기 위한 것입니다.

특성 구문 및 속성 요소 구문과 SDK 설명서에서 XAML 구문을 설명할 때 사용되는 기타 용어에 대한 자세한 내용은 XAML 구문 용어를 참조하십시오. 사용자 지정 클래스를 만들 때 XAML의 사용을 고려하는 경우에는 XAML 구문 용어 항목부터 시작하는 것도 좋은 방법입니다.

XAML 루트 요소 및 XML 네임스페이스

XAML 파일에는 하나의 루트 요소만 있어야 올바른 형식의 XML 파일이자 유효한 XAML 파일이 될 수 있습니다. 일반적으로 응용 프로그램 모델의 일부인 요소를 선택해야 합니다(예: 페이지의 경우 Window 또는 Page, 외부 사전의 경우 ResourceDictionary, 응용 프로그램 정의 루트의 경우 Application). 다음 예제에서는 루트 요소가 Page인 WPF 페이지에 대한 일반적인 XAML 파일의 루트 요소를 보여 줍니다.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"


...


</Page>

루트 요소에는 특성 xmlns와 xmlns:x도 포함됩니다. 이러한 특성은 태그가 참조할 요소의 요소 정의가 포함된 XML 네임스페이스를 XAML 프로세서에 알려 줍니다. xmlns 특성은 특히 기본 XML 네임스페이스를 나타냅니다. 기본 XML 네임스페이스 안에서는 태그의 개체 요소를 접두사 없이 지정할 수 있습니다. 대부분의 WPF 응용 프로그램 시나리오 및 SDK의 WPF 단원에 나오는 거의 모든 예제의 경우 기본 XML 네임스페이스는 WPF 네임스페이스 https://schemas.microsoft.com/winfx/2006/xaml/presentation에 매핑됩니다. xmlns:x 특성은 XAML 언어 네임스페이스 https://schemas.microsoft.com/winfx/2006/xaml에 매핑되는 추가적인 XML 네임스페이스를 나타냅니다. 이 매핑이 있는 파일의 태그에서 참조될 때 XAML 사양에 정의된 필수 언어 구성 요소 앞에는 x:가 접두사로 붙습니다. xmlns을 사용하여 사용 및 매핑의 범위를 정의하는 방식은 XML 1.0 사양과 일치합니다. xmlns 특성은 태그에서 제공되는 경우 각 페이지의 루트 요소 및 응용 프로그램 정의에서만 엄격하게 필수입니다. xmlns 정의는 루트의 모든 자식 요소에 적용되며 이 동작은 xmlns에 대한 XML 1.0 사양과 일치합니다. xmlns 특성 역시 루트 아래의 다른 요소에서 허용되며 정의 요소의 모든 자식 요소에 적용됩니다. 하지만 XML 네임스페이스를 자주 정의하거나 다시 정의하면 XAML 태그 스타일의 가독성이 떨어질 수 있으므로 이와 같은 사용은 일반적이지 않습니다.

프로젝트 빌드 파일의 일부인 구성 때문에 WPF 어셈블리에는 기본 XML 네임스페이스에 대한 WPF 매핑을 지원하는 형식이 포함되어 있습니다. 어셈블리는 대상 파일에서도 매핑됩니다. 따라서 WPF 어셈블리의 XAML 요소를 참조하기 위해서는 xmlns만 매핑하면 됩니다. 사용자 지정 어셈블리 또는 WPF 외부의 어셈블리에 대해서는 어셈블리를 xmlns 매핑의 일부로 지정할 수 있습니다. 일반적으로는 다른 접두사를 선택하지만 다른 XML 네임스페이스를 기본값으로 선택한 다음 WPF를 접두사에 매핑할 수도 있습니다. XML 네임스페이스와 어셈블리 백업 코드의 네임스페이스가 어떻게 관련되는지에 대한 자세한 내용은 XAML 네임스페이스 및 네임스페이스 매핑을 참조하십시오.

x: 접두사

앞의 루트 요소 예제에서 접두사 x:는 XAML XML 네임스페이스 https://schemas.microsoft.com/winfx/2006/xaml의 매핑에 사용되었습니다. 이 x: 접두사는 이 SDK 전체의 설명서, 예제 및 프로젝트 템플릿에서 XAML XML 네임스페이스를 매핑하는 데 사용됩니다. x: prefix/XAML XML 네임스페이스에는 XAML에서 자주 사용하게 될 몇 가지 프로그래밍 구조체가 포함되어 있습니다. 다음은 가장 많이 사용하게 될 x: prefix/XAML 네임스페이스 프로그래밍 구조체의 목록입니다.

  • x:Key: ResourceDictionary의 각 리소스에 대한 고유 키를 설정합니다 x:Key는 응용 프로그램 태그에서 보게 될 x: 사용의 90%를 차지할 것입니다.

  • x:Class: CLR 네임스페이스 및 XAML 페이지에 대한 코드 숨김을 제공하는 클래스의 클래스 이름을 지정합니다. 이러한 클래스가 코드 숨김을 지원하도록 해야 하며 바로 이런 이유 때문에 리소스가 없는 경우에도 x:가 매핑된 것을 자주 보게 됩니다.

  • x:Name: 개체 요소가 처리된 후 런타임 코드에 있는 인스턴스에 대한 런타임 개체 이름을 지정합니다. 해당 WPF 프레임워크 수준 Name 속성이 지원되지 않는 요소를 지정하는 경우에 x:Name을 사용합니다. 이는 특정 애니메이션 시나리오에서 볼 수 있는 상황입니다.

  • x:Static: XAML 호환 속성이 아닌 정적 값을 가져오는 값 참조를 사용할 수 있게 합니다.

  • x:Type: 형식 이름을 기반으로 Type 참조를 생성합니다. Style.TargetType과 같은 Type을 사용하는 특성을 지정하는 데 사용합니다. 하지만 대개의 경우 속성에는 기본 문자열 대 Type 변환이 있으므로 x:Type 사용은 선택 사항입니다.

x: prefix/XAML 네임스페이스에는 일반적으로는 사용되지 않는 추가적인 프로그래밍 구조체가 있습니다. 자세한 내용은 XAML 네임스페이스(x:) 언어 기능을 참조하십시오.

이벤트 및 XAML 코드 숨김

대부분의 WPF 응용 프로그램은 태그와 코드 숨김으로 구성됩니다. 프로젝트에서 XAML은 .xaml 파일로 작성되며 코드 숨김 파일은 Microsoft Visual Basic .NET 또는 C# 등의 CLR 언어를 사용하여 작성됩니다. XAML 파일이 컴파일될 때 각 XAML 페이지에 대한 XAML 코드 숨김 파일의 위치는 네임스페이스와 클래스를 XAML 페이지 루트 요소의 x:Class 특성으로 지정하여 식별합니다.

지금까지의 예제에서 몇 개의 단추를 살펴보았지만 아직 논리적 동작이 연결된 단추는 없었습니다. 개체 요소에 대한 동작을 추가하는 기본 응용 프로그램 수준 메커니즘은, 요소 클래스의 기존 이벤트를 사용하고 런타임에서 해당 이벤트가 발생할 때 호출되는 해당 이벤트에 대한 특정 처리기를 작성하는 것입니다. 사용할 이벤트 이름과 처리기 이름은 태그에서 지정하고 처리기를 구현하는 코드는 코드 숨김에서 정의합니다.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MyNamespace.MyPageCode">
  <Button Click="ClickHandler" >Click Me!</Button>
</Page>
namespace MyNamespace
{
  public partial class MyPageCode
  {
    void ClickHandler(object sender, RoutedEventArgs e)
    {
      Button b = e.Source as Button;
      b.Background = Brushes.Red;
    }
  }
}

코드 숨김 파일은 CLR 네임스페이스 MyNamespace를 사용하며 MyPageCode를 해당 네임스페이스 안에서 partial 클래스로 선언합니다. 이는 태그 루트에 제공되는 MyNamespace.MyPageCode의 x:Class 특성 값과 비교됩니다. 컴파일러는 루트 요소 형식에서 클래스를 파생하여 모든 컴파일된 XAML 페이지에 대한 partial 클래스를 자동으로 만듭니다. 같은 partial 클래스를 정의하는 코드 숨김을 제공하는 경우, 결과 코드는 컴파일된 응용 프로그램의 동일한 네임스페이스와 클래스 안에서 결합됩니다.

코드 숨김 프로그래밍의 요구 사항에 대한 자세한 내용은 코드 숨김 및 XAML의 "코드 숨김, 이벤트 처리기 및 partial 클래스 요구 사항" 단원을 참조하십시오.

별도의 코드 숨김 파일을 만들지 않으려면 코드를 XAML 파일 안에 인라인으로 넣을 수도 있습니다. 하지만 인라인 코드는 제한이 많은 기술입니다. 자세한 내용은 코드 숨김 및 XAML을 참조하십시오.

이벤트 특성 구문

태그에서 이벤트를 통해 동작을 지정할 때는 일반적으로 특성 구문을 사용하여 처리기를 연결합니다. 이벤트 특성이 지정된 개체 요소는 이벤트를 수신하고 처리기를 호출하는 인스턴스가 됩니다. 처리하고자 하는 특정 이벤트의 이름이 특성 이름입니다. 특성 값은 정의할 처리기의 메서드 이름입니다. 그런 다음 해당 이벤트에 대한 대리자를 기반으로 하는 처리기와 함께 처리기 구현을 코드 숨김에서 제공해야 합니다. 코드 숨김의 처리기는 Microsoft Visual Basic .NET 또는 C# 등의 프로그래밍 언어로 작성합니다.

각 WPF 이벤트는 이벤트가 발생할 때 이벤트 데이터를 보고합니다. 이벤트 처리기는 이 이벤트 데이터에 액세스할 수 있습니다. 앞의 예제에서 처리기는 이벤트 데이터를 통해 보고된 이벤트 소스를 가져온 다음 해당 소스에 대해 속성을 설정합니다.

라우트된 이벤트

WPF에 고유하며 기본이 되는 라우트된 이벤트라는 기능이 있습니다. 라우트된 이벤트를 사용하면 요소가 다른 요소에 의해 발생한 이벤트를 처리할 수 있습니다. 단, 요소들이 요소 트리 관계를 통해 연결되어 있어야 합니다. XAML 특성을 사용하여 이벤트 처리를 지정할 때 라우트된 이벤트는 클래스 멤버 표에서 해당 이벤트를 나열하지 않는 요소를 포함하여 모든 요소에서 수신되고 처리될 수 있습니다. 이렇게 하려면 소유 클래스 이름으로 이벤트 이름 특성을 정규화합니다. 예를 들어, StackPanel / Button 예제의 부모 StackPanel은 처리기 이름을 특성 값으로 사용하고 StackPanel 개체 요소에 대해 Button.Click 특성을 지정하여 자식 요소 단추의 Click 이벤트에 대한 처리기를 등록할 수 있습니다. 자세한 내용은 라우트된 이벤트 개요를 참조하십시오.

x:Name

기본적으로 개체 요소 처리를 통해 만들어진 개체 인스턴스는 코드에서 사용할 수 있는 개체 참조를 상속하거나 고유한 식별자를 가지지 않습니다. 코드에서 생성자를 호출할 때는 나중에 코드에서 인스턴스를 참조할 수 있도록 대개는 생성자 결과를 사용하여 변수를 생성된 인스턴스로 설정합니다. 태그 정의를 통해 만들어진 개체에 대한 표준화된 액세스를 제공하기 위해 XAML은 x:Name 특성 을 정의합니다. 모든 개체 요소에 대해 x:Name 특성의 값을 설정할 수 있습니다. 코드 숨김에서, 선택하는 식별자는 생성된 인스턴스를 참조하는 인스턴스 변수와 동일합니다. 명명된 요소는 모든 측면에서 개체 인스턴스인 것처럼 작동하며(이름은 해당 인스턴스를 참조만 함) 코드 숨김은 명명된 요소를 참조하여 응용 프로그램 안에서 런타임 상호 작용을 처리할 수 있습니다.

WPF 프레임워크 수준 XAML 요소는 XAML에 정의된 x:Name 특성과 동일한 Name 속성을 상속합니다. 다른 특정 클래스에서도 x:Name에 해당하는 속성 수준 속성을 제공하며 이것은 일반적으로 Name 속성으로도 정의됩니다. 일반적으로, 멤버 표에서 선택한 요소의 Name 속성을 찾을 수 없는 경우 x:Name을 대신 사용합니다.

다음 예제에서는 StackPanel 요소에 Name을 설정합니다. 그런 다음 해당 StackPanel 내의 Button에 대한 처리기가 Name에 설정된 대로 인스턴스 참조 buttonContainer를 통해 StackPanel을 참조합니다.

<StackPanel Name="buttonContainer">


...


  <Button Click="RemoveThis">Click to remove this button</Button>
</StackPanel>
void RemoveThis(object sender, RoutedEventArgs e)
{
    FrameworkElement fe = e.Source as FrameworkElement;
    if (buttonContainer.Children.Contains(fe))
    {
        buttonContainer.Children.Remove(fe);
    }
}

변수와 마찬가지로 인스턴스 이름도 범위라는 개념으로 제어됩니다. 즉, 예측 가능한 특정 범위 내에서 이름이 고유해야 합니다. 페이지를 정의하는 기본 태그는 해당 페이지의 루트 요소인 이름 범위 경계를 사용하여 하나의 고유한 이름 범위를 지정합니다. 하지만 다른 태그 소스는 런타임에 스타일 안의 템플릿 또는 스타일과 같은 페이지와 상호 작용할 수 있으며, 이러한 태그 소스에는 페이지의 이름 범위와 연결되지 않아도 되는 자체 이름 범위가 있는 경우가 많습니다. x:Name 및 이름 범위에 대한 자세한 내용은 Name, x:Name 특성 또는 WPF 이름 범위를 참조하십시오.

연결된 속성 및 연결된 이벤트

XAML에서는 특정 속성이나 이벤트를 속성이나 이벤트가 설정되는 요소에 대한 멤버 표에 존재하는지 여부에 관계 없이 모든 요소에서 지정할 수 있게 하는 언어 기능을 지정합니다. 이 기능의 속성 버전을 연결된 속성이라고 하고 이벤트 버전을 연결된 이벤트라고 합니다. 개념적으로 볼 때 연결된 속성과 연결된 이벤트는 해당 클래스 계층 구조에 관계 없이 모든 요소/클래스에 설정할 수 있는 전역 멤버로 생각할 수 있습니다.

XAML의 연결된 속성은 일반적으로 특성 구문을 통해 사용합니다. 특성 구문에서는 연결된 속성을 OwnerType.PropertyName의 형식으로 지정합니다. 이는 속성 요소 사용과 비슷해 보이지만 이 경우 지정하는 OwnerType은 연결된 속성이 설정되는 개체 요소와 형식이 항상 다릅니다. OwnerType은 연결된 속성 값을 가져오거나 설정하기 위해 XAML 프로세서에 필요한 접근자 메서드를 제공하는 형식입니다. 연결된 속성에 대한 가장 일반적인 시나리오는 자식 요소가 부모 요소에 속성 값을 보고하도록 하는 것입니다.

다음 예제에서는 DockPanel.Dock 연결된 속성을 보여 줍니다. DockPanel 클래스는 DockPanel.Dock에 대한 접근자를 정의하며 따라서 연결된 속성을 소유합니다. DockPanel 클래스에는 자식 요소를 반복하고 각 요소에서 DockPanel.Dock의 설정 값을 검사하는 논리도 포함됩니다. 값이 발견되면 레이아웃 도중 이 값을 사용하여 자식 요소를 배치합니다. DockPanel 클래스에 대한 시나리오도 DockPanel.Dock 연결된 속성 및 이 위치 지정 기능을 사용하기 위해서입니다.

<DockPanel>
  <Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
  <Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>

WPF(Windows Presentation Foundation)에서 모든 연결된 속성은 종속성 속성으로도 구현됩니다. 자세한 내용은 연결된 속성 개요를 참조하십시오.

연결된 속성은 비슷한 OwnerType.EventName 특성 구문 형식을 사용합니다. 연결되지 않은 이벤트와 마찬가지로 XAML의 연결된 이벤트에 대한 특성 값은 이벤트가 요소에서 처리될 때 호출되는 처리기 메서드의 이름을 지정합니다.

연결된 이벤트가 사용되는 한 가지 시나리오는 마우스 단추와 같이 모든 요소에서 처리될 수 있는 장치 입력 이벤트입니다. 이러한 연결된 이벤트의 예로 Mouse.MouseDown을 들 수 있습니다. 하지만 대부분의 WPF 프레임워크 수준 요소는 연결된 이벤트를 사용하지 않고 이 이벤트를 사용할 수 있습니다. 이는 기본 요소 클래스 UIElementMouse.MouseDown 연결된 이벤트에 대한 별칭을 만들고 해당 별칭을 UIElement 멤버 표에 MouseDown으로 노출하기 때문입니다. 따라서 일반적으로 XAML 페이지 또는 WPF(Windows Presentation Foundation) 응용 프로그램 프로그래밍에서는 연결된 이벤트 구문을 지정할 필요가 없습니다. 사용자 지정 요소를 사용하거나, 드물기는 하지만 UIElement에서 파생되지 않지만 시각적 표현은 있는 개체 요소를 사용하는 경우는 예외입니다. WPF에서 모든 연결된 이벤트는 라우트된 이벤트로도 구현됩니다. ContentElement는 유동 문서 모델에서 사용할 수 있도록 입력 이벤트에 대한 별칭도 노출합니다. 자세한 내용은 라우트된 이벤트 개요입력 개요를 참조하십시오.

XAML 페이지 루트 요소 분석

다음 표에서는 일반적인 XAML 페이지 루트 요소를 상세히 표시하여 이 항목에서 다루는 루트 요소의 특정 특성을 보여 줍니다.

<Page

루트 요소를 여는 개체 요소

xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

기본(WPF) 네임스페이스

xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

XAML 네임스페이스

x:Class="MyNamespace.MyPageCode"

이 샘플 partial 클래스에 정의된 모든 코드 숨김에 태그를 연결하는 partial 클래스 선언

>

루트에 대한 개체 요소의 끝(페이지에 자식 요소가 있기 때문에 아직 닫히지 않음)

기본 클래스 및 XAML

기본 XAML 및 해당 스키마는 XAML에서 사용될 태그 요소이자 CLR 개체에 해당하는 클래스의 컬렉션입니다. 하지만 모든 클래스를 요소에 매핑할 수 있는 것은 아닙니다. ButtonBase와 같은 추상 클래스 및 특정 비추상 기본 클래스는 CLR 개체 모델에서 상속에 사용되며 해당 XAML 태그를 지원하지 않습니다. 각각의 구체적인 XAML 요소는 계층 구조의 일부 기본 클래스에서 멤버를 상속하기 때문에 추상 클래스를 포함한 기본 클래스는 여전히 XAML 개발에 있어서 중요합니다. 이러한 멤버에는 대개 요소에서 특성으로 설정할 수 있는 속성 또는 처리될 수 있는 이벤트가 포함됩니다. FrameworkElement는 WPF 프레임워크 수준에서 WPF의 구체적 기본 UI 클래스입니다. UI를 디자인할 때는 모두 FrameworkElement에서 파생되는 다양한 도형, 패널, 데코레이터 또는 컨트롤 클래스를 사용합니다. 관련 기본 클래스인 FrameworkContentElementFrameworkElement에서 의도적으로 API를 미러링하는 API를 사용하여, 유동 레이아웃 표현에 잘 작동하는 문서 지향적 요소를 지원합니다. 요소 수준 및 CLR 개체 모델에서 특성의 조합은 정확한 요소 형식 및 해당 기본 클래스에 관계 없이 구체적 XAML 요소의 대부분에 설정할 수 있는 공통 속성 집합을 제공합니다.

XAML 보안

XAML은 개체 인스턴스화 및 실행을 직접적으로 나타내는 태그 언어입니다. 따라서 XAML에서 만든 요소에는 생성된 해당 코드가 수행하는 것과 마찬가지로 시스템 리소스(예: 네트워크 액세스, 파일 시스템 IO)와 상호 작용하는 동일한 기능이 있습니다.

WPF에서는 .NET 보안 프레임워크인 CAS(코드 액세스 보안)를 지원합니다. 즉, 인터넷 영역에서 실행되는 WPF 콘텐츠는 실행 권한이 줄어듭니다. "느슨한 XAML"(컴파일되지 않은 XAML의 페이지가 로드 시 XAML 뷰어에 의해 해석됨) 및 XBAP(XAML 브라우저 응용 프로그램)는 일반적으로 이 인터넷 영역에서 실행되며 같은 권한 집합을 사용합니다. 하지만 완전히 신뢰할 수 있는 응용 프로그램으로 로드된 XAML은 시스템 리소스에 대해 호스팅 응용 프로그램과 동일한 액세스 권한을 가집니다. 자세한 내용은 Windows Presentation Foundation 부분 신뢰 보안을 참조하십시오.

코드에서 XAML 로드

XAML을 사용하여 전체 UI를 정의할 수 있지만 XAML에서 UI의 일부만 정의하는 것이 적합할 때도 있습니다. 이 기능을 통해 부분 사용자 지정, 정보의 로컬 저장, XAML을 사용한 비즈니스 개체 제공을 비롯한 가능한 다양한 시나리오를 지원할 수 있습니다. 이러한 시나리오에서 핵심 역할을 하는 것은 XamlReader 클래스 및 해당 Load 메서드입니다. 입력은 XAML 파일이며 출력은 해당 태그에서 만들어진 개체의 전체 런타임 트리를 나타내는 개체입니다. 그런 다음 응용 프로그램에 이미 존재하는 다른 개체의 속성으로 개체를 삽입할 수 있습니다. 속성이 표시 기능을 가지고 있으며 응용 프로그램에 새 콘텐츠가 추가되었음을 실행 엔진에 알리는 콘텐츠 모델의 적절한 속성인 경우에는 XAML에 로드하여 실행 중인 응용 프로그램의 콘텐츠를 쉽게 수정할 수 있습니다. 하지만 이 기능은 실행되는 응용 프로그램에 파일을 로드함으로써 보안에 가져올 수 있는 영향을 감안하여 일반적으로 완전히 신뢰할 수 있는 응용 프로그램에서만 사용할 수 있게 되어 있습니다.

새로운 기능

이 항목에서는 XAML 구문 개념과 용어에 대한 기본적인 내용을 소개했습니다. 이 항목에서 사용된 용어에 대한 자세한 내용은 XAML 구문 용어를 참조하십시오.

Windows Presentation Foundation 시작 자습서를 아직 읽지 않았다면 읽어보십시오. 자습서에서 설명하는 태그 응용 프로그램을 실제로 만들어보면 이 항목에서 설명하는 많은 개념을 더 확실하게 이해할 수 있을 것입니다.

WPF에서는 Application 클래스를 기반으로 하는 특정 응용 프로그램 모델을 사용합니다. 자세한 내용은 응용 프로그램 관리 개요를 참조하십시오.

WPF 응용 프로그램 만들기(WPF)에서는 명령줄에서, 그리고 Microsoft Visual Studio를 사용하여 XAML 포함 응용 프로그램을 만드는 방법에 대해 더 자세하게 설명합니다.

종속성 속성 개요에서는 WPF(Windows Presentation Foundation)의 다양한 속성에 대해 자세히 설명하고 종속성 속성의 개념을 소개합니다.

마지막으로 SDK에는 XAMLPad라는 XAML 도구가 포함되어 있습니다. 이 도구를 사용하면 XAML로 작업하고 그 결과를 실시간으로 확인할 수 있습니다.

참고 항목

개념

XAMLPad

XAML 및 사용자 지정 클래스

기본 요소 개요

WPF의 트리

기타 리소스

XAML 네임스페이스(x:) 언어 기능

WPF 네임스페이스 XAML 확장

콘텐츠 모델