다음을 통해 공유


XAML 노드 스트림 구조 및 개념 이해

.NET Framework XAML 서비스로 구현된 XAML 판독기와 XAML 작성기는 XAML 노드 스트림의 디자인 개념을 기반으로 합니다. XAML 노드 스트림은 XAML 노드 집합을 개념화한 것입니다. 이 개념화된 XAML 노드 스트림에서 XAML 프로세서는 XAML의 노드 관계 구조를 한 번에 하나씩 진행합니다. 항상 하나의 현재 레코드 또는 현재 위치만 열려 있는 XAML 노드 스트림에 존재하며, API의 많은 요소는 해당 위치에서 사용할 수 있는 정보만 보고합니다. XAML 노드 스트림의 현재 노드는 개체, 멤버 또는 값으로 설명될 수 있습니다. XAML을 XAML 노드 스트림으로 처리하여 XAML 판독기는 XAML 작성기와 통신할 수 있으며 XAML을 포함하는 로드 경로 또는 저장 경로 작업 도중에 프로그램에서는 XAML 노드 스트림 내용의 표시, 상호 작용 또는 변경을 수행할 수 있습니다. XAML 판독기 및 작성기 API 디자인과 XAML 노드 스트림 개념은 XML Document Object Model (DOM)과 XmlReaderXmlWriter 클래스 같은 이전의 관련된 판독기 및 작성기의 디자인 및 개념과 비슷합니다. 이 항목에서는 XAML 노드 스트림 개념을 논의하고 XAML 노드 수준에서 XAML 표현과 상호 작용하는 루틴을 작성할 수 있는 방법에 대해 설명합니다.

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

  • XAML 판독기에 XAML 로드
  • 기본 읽기 노드 루프
  • 현재 노드 작업
  • 개체 노드 트래버스 및 진입
  • 값 변환기 및 XAML 노드 스트림
  • XAML 노드 스트림의 XAML 및 XML 언어에서 정의된 멤버
  • 노드 순서
  • 관련 항목

XAML 판독기에 XAML 로드

기본 XamlReader 클래스는 초기 XAML을 XAML 판독기에 로드하기 위한 특정 기법을 선언하지 않습니다. 대신 파생 클래스에서 XAML의 입력 소스에 대한 특징 및 제약 조건을 포함하여 로드 기법을 선언하고 구현합니다. 예를 들어 XamlObjectReader는 루트 또는 기준을 나타내는 단일 개체의 입력 소스에서 시작하여 개체 그래프를 읽습니다. 그런 다음 XamlObjectReader는 개체 그래프에서 XAML 노드 스트림을 생성합니다.

.NET Framework XAML 서비스에서 정의된 가장 중요한 XamlReader 서브클래스는 XamlXmlReader입니다. XamlXmlReader는 텍스트 파일을 스트림 또는 파일 경로를 통해 직접 로드하거나 TextReader와 같은 관련된 판독기 클래스를 통해 간접적으로 로드하여 초기 XAML을 로드합니다. 로드된 후 XamlReader는 XAML 입력 소스 전체를 포함하는 것으로 간주할 수 있습니다. 그러나 XamlReader 기본 API는 판독기가 XAML의 단일 노드와 상호 작용하도록 설계되었습니다. 처음 로드될 때 나타나는 첫 번째 단일 노드는 XAML의 루트와 해당 시작 개체입니다.

XAML 노드 스트림 개념

일반적으로 XML 기반 기술에 액세스하는 데 DOM, 트리 비유 또는 쿼리 기반 방법을 사용하는 것이 더 익숙한 경우 XAML 노드 스트림을 개념화하는 데 유용한 방법은 다음과 같습니다. 로드한 XAML이 가능한 모든 노드가 항상 확장되어 있고 선형으로 표시된 DOM 또는 트리라고 가정합니다. 노드를 이동할 때는 DOM과 관련이 있는 수준이지만 해당 수준 개념이 노드 스트림과 관련이 없기 때문에 XAML 노드 스트림에서 명시적으로 추적하지는 않는 수준의 "내부" 또는 "외부"를 순회하게 됩니다. 노드 스트림에는 "현재" 위치가 있지만 스트림의 다른 부분을 참조로 저장하지 않은 경우에는 현재 노드 위치 이외의 모든 노드 스트림 요소가 보이지 않습니다.

XAML 노드 스트림 개념의 큰 장점은 노드 스트림 전체를 거치고 나면 전체 XAML 표현을 처리한 것으로 확인할 수 있다는 점입니다. 따라서 쿼리, DOM 작업 또는 다른 비선형 정보 처리 방법이 전체 XAML 표현의 일부를 누락했을까봐 걱정할 필요가 없습니다. 이러한 이유 때문에 XAML 노드 스트림 표현은 XAML 판독기와 XAML 작성기를 연결하는 데 이상적일 뿐 아니라 XAML 처리 작업의 읽기 및 쓰기 단체 사이에서 작동하는 프로세스를 삽입할 수 있는 시스템을 제공하는 데도 이상적입니다. 대부분의 경우 XAML 노드 스트림의 노드 순서는 신중하게 최적화되거나, 소스 텍스트, 바이너리 또는 개체 그래프에 나타나는 순서와 비교하여 XAML 판독기에 의해 다시 정렬됩니다. 이 동작은 XAML 작성기가 노드 스트림에서 "뒤로" 이동해야 하는 위치에 있지 않도록 하는 XAML 처리 아키텍처를 적용하기 위한 것입니다. 모든 XAML 쓰기 작업은 스키마 컨텍스트와 노드 스트림의 현재 위치를 기반으로 수행되는 것이 가장 좋습니다.

기본 읽기 노드 루프

XAML 노드 스트림을 검사하기 위한 기본 읽기 노드 루프는 다음 개념으로 구성됩니다. 이 항목에 설명된 노드 루프의 관점에서 사용자는 XamlXmlReader를 사용하여 사람이 읽을 수 있는 텍스트 기반의 XAML 파일을 읽는 중이라고 가정합니다. 이 단원에 있는 링크를 사용하여 XamlXmlReader에서 구현하는 특정 XAML 노드 루프 API를 참조할 수 있습니다.

  • IsEof를 확인하거나 Read() 반환 값을 사용하여 현재 XAML 노드 스트림의 끝에 있지 않은지 확인합니다. 스트림의 끝에 있는 경우에는 현재 노드가 없으므로 종료해야 합니다.

  • NodeType을 호출하여 XAML 노드 스트림이 현재 노출하는 노드의 유형을 확인합니다.

  • 직접 연결된 관련 XAML 개체 작성기가 있는 경우 일반적으로 이 시점에서 WriteNode를 호출합니다.

  • 현재 노드 또는 현재 레코드로 보고되는 XamlNodeType을 기초로 다음 중 하나를 호출하여 노드 콘텐츠에 대한 정보를 가져옵니다.

    • NodeTypeStartMember 또는 EndMember인 경우에는 Member를 호출하여 멤버에 대한 XamlMember 정보를 가져옵니다. 멤버는 XamlDirective일 수 있으며 따라서 반드시 이전 개체의 일반 형식으로 정의된 멤버인 것은 아닙니다. 예를 들어 개체에 적용된 x:Name은 IsDirective가 true이고 멤버의 Name이 Name인 XAML 멤버로 나타납니다. 다른 속성은 이 지시문이 XAML 언어의 XAML 네임스페이스 아래에 있음을 나타냅니다.

    • NodeTypeStartObject 또는 EndObject인 경우에는 Type을 호출하여 개체에 대한 XamlType 정보를 가져옵니다.

    • NodeTypeValue인 경우에는 Value를 호출합니다. 노드는 멤버 값의 가장 간단한 식이거나 개체에 대한 초기화 텍스트인 경우에만 값이 됩니다. 그러나 이 항목의 이후 단원에 설명된 형식 변환 동작에 대해 알고 있어야 합니다.

    • NodeTypeNamespaceDeclaration인 경우에는 Namespace를 호출하여 네임스페이스 노드에 대한 네임스페이스 정보를 가져옵니다.

  • Read를 호출하여 XAML 판독기를 XAML 노드 스트림의 다음 노드로 이동하고 단계를 다시 반복합니다.

.NET Framework XAML 서비스 XAML 판독기가 제공하는 XAML 노드 스트림은 가능한 모든 노드를 항상 완전히 통과합니다. XAML 노드 루프에 대한 일반적인 흐름 제어 기술에는 while (reader.Read()) 내에서 본문을 정의하고 노드 루프의 각 노드 지점에서 NodeType을 전환하는 과정이 포함됩니다.

노드 스트림이 파일 끝에 있는 경우 현재 노드는 null입니다.

판독기 및 작성기를 사용하는 가장 간단한 루프는 다음 예와 유사합니다.

XamlXmlReader xxr = new XamlXmlReader(new StringReader(xamlStringToLoad));
//where xamlStringToLoad is a string of well formed XAML
XamlObjectWriter xow = new XamlObjectWriter(xxr.SchemaContext);
while (xxr.Read()) {
  xow.WriteNode(xxr);
}

예로 든 이 기본적인 로드 경로 XAML 노드 루프에서는 XAML 판독기와 XAML 작성기를 투명하게 연결하며 XamlServices.Parse를 사용한 경우와 다른 작업을 수행하지 않습니다. 그러나 이 기본 구조는 읽기 또는 쓰기 시나리오에 적용되기 위해 확장됩니다. 가능한 일부 시나리오는 다음과 같습니다.

  • NodeType을 전환합니다. 읽을 노드 형식에 따라 다른 작업을 수행합니다.

  • 모든 경우에 WriteNode를 호출하지 않습니다. 일부 NodeType 경우에서만 WriteNode를 호출합니다.

  • 특정 노드 형식에 대한 논리 내에서 해당 노드의 정보를 분석하고 노드에 대해 작업을 수행합니다. 예를 들어 특정 XAML 네임스페이스에서 제공된 개체만 작성하고 해당 XAML 네임스페이스에서 제공되지 않은 모든 개체를 삭제하거나 지연할 수 있습니다. 또는 XAML 시스템에서 멤버 처리의 일부로 지원하지 않는 모든 XAML 지시문을 삭제하거나 다시 처리할 수도 있습니다.

  • XAML 스키마 컨텍스트를 우회하는 형식 매핑을 수행할 수 있도록 Write* 메서드를 재정의하는 사용자 지정 XamlObjectWriter를 정의합니다.

  • XAML 동작의 사용자 지정된 차이점이 판독기와 작성기 모두에서 사용되도록 기본이 아닌 XAML 스키마 컨텍스트를 사용하는 XamlXmlReader를 생성합니다.

노드 루프 개념을 벗어난 XAML 액세스

XAML 노드 루프로서가 아닌 다른 방법으로 XAML 표현에 대한 작업을 수행할 수 있습니다. 예를 들어 인덱싱된 노드를 읽을 수 있거나 특히 x:Name, x:Uid 또는 다른 식별자를 통해 노드에 직접 액세스하는 XAML 판독기가 존재할 수 있습니다. .NET Framework XAML 서비스는 전체 구현을 제공하지 않지만 서비스 및 지원 형식을 통해 제안된 패턴을 제공합니다. 자세한 내용은 IXamlIndexingReaderXamlNodeList를 참조하십시오.

팁

Microsoft에서는 Microsoft XAML Toolkit이라는 번외 릴리스도 제공합니다.이 번외 릴리스는 아직 시험판 단계에 있습니다.그러나 시험판 구성 요소를 사용하려는 사용자를 위해 Microsoft XAML Toolkit에서는 XAML 도구와 정적 XAML 분석을 위한 몇 가지 흥미로운 리소스를 제공합니다.Microsoft XAML Toolkit에는 XAML DOM API, FxCop 분석 지원 및 Silverlight용 XAML 스키마 컨텍스트가 포함되어 있습니다.자세한 내용은 Microsoft XAML Toolkit을 참조하십시오.

현재 노드 작업

XAML 노드 루프를 사용하는 대부분의 시나리오에서는 노드를 읽기만 하지는 않습니다. 대부분의 시나리오에서는 현재 노드를 처리하고 각 노드를 한 번에 하나씩 XamlWriter 구현에 전달합니다.

일반적인 로드 경로 시나리오에서는 XamlXmlReader가 XAML 노드 스트림을 생성하고, XAML 노드가 사용자의 논리와 XAML 스키마 컨텍스트에 따라 처리된 다음, 이 노드가 XamlObjectWriter에 전달됩니다. 그런 다음 사용자가 결과 개체 그래프를 응용 프로그램이나 프레임워크에 통합합니다.

일반적인 저장 경로 시나리오에서는 XamlObjectReader가 개체 그래프를 읽고, 개별 XAML 노드가 처리된 다음, XamlXmlWriter가 serialize된 결과를 XAML 텍스트 파일로 출력합니다. 핵심은 두 경로 및 시나리오 모두 한 번에 정확히 하나의 XML 노드에 대해 작업하며, XAML 노드를 XAML 형식 시스템 및 일반 .NET Framework XAML 서비스 API에 의해 정의된 표준화된 방식으로 처리할 수 있다는 점입니다.

프레임 및 범위

XAML 노드 루프는 XAML 노드 스트림을 선형 방식으로 순환합니다. 노드 스트림은 개체, 다른 개체를 포함하는 멤버 등의 순서로 통과합니다. 프레임 및 스택 개념을 구현하여 XAML 노드 스트림 내에서 범위를 추적하는 것이 일반적으로 유용합니다. 특히 현재 작업 중인 노드 스트림을 적극적으로 조정하는 경우에 유용합니다. 노드 루프 논리의 일부로 구현하는 프레임 및 스택 지원에서는 XAML 노드 구조가 DOM 관점에 속한 경우 해당 노드 구조에서 아래로 내려갈 때 StartObject(또는 GetObject) 및 EndObject 범위를 계산할 수 있습니다.

개체 노드 트래버스 및 진입

XAML 판독기에 의해 열릴 때 노드 스트림의 첫 번째 노드는 루트 개체의 시작 개체 노드입니다. 정의에 따라 이 개체는 항상 단일 개체 노드이며 피어가 없습니다. 모든 실제 XAML 예에서 루트 개체는 개체를 더 포함하는 하나 이상의 속성을 갖도록 정의되며 이러한 속성에는 멤버 노드가 있습니다. 멤버 노드는 하나 이상의 개체 노드를 포함하거나 대신 값 노드에서 종료될 수도 있습니다. 루트 개체는 일반적으로 XAML 이름 범위를 정의하며, 이 이름 범위는 XAML 텍스트 태그에서는 구문에 따라 특성으로 할당되지만 XAML 노드 스트림 표현에서는 Namescope 노드 형식에 매핑됩니다.

다음 XAML 예제를 살펴보겠습니다. 이 예제는 임의의 XAML이며 .NET Framework에 있는 기존 형식의 지원을 받지 않습니다. 이 개체 모델에서는 FavorCollection이 Favor의 List<T>이고, Balloon 및 NoiseMaker가 Favor에 할당 가능하며, Balloon.Color 속성이 WPF에서 알려진 색 이름으로 색을 정의하는 방식과 유사한 Color 개체의 지원을 받고, Color가 특성 구문에 대한 형식 변환기를 지원한다고 가정합니다.

XAML 태그

결과 XAML 노드 스트림

<Party

Party에 대한 Namespace 노드

xmlns="PartyXamlNamespace">

Party에 대한 StartObject 노드

  <Party.Favors>

Party.Favors에 대한 StartMember 노드

암시적 FavorCollection에 대한 StartObject 노드

암시적 FavorCollection 항목 속성에 대한 StartMember 노드

    <Balloon

Balloon에 대한 StartObject 노드

      Color="Red"

Color에 대한 StartMember 노드

  특성 값 문자열 "Red"에 대한 Value 노드

Color에 대한 EndMember

      HasHelium="True"

HasHelium에 대한 StartMember 노드

  특성 값 문자열 "True"에 대한 Value 노드

HasHelium에 대한 EndMember

    >

Balloon에 대한 EndObject

    <NoiseMaker>Loudest</NoiseMaker>

NoiseMaker에 대한 StartObject 노드

  _Initialization에 대한 StartMember 노드

    초기화 값 문자열 "Loudest"에 대한 Value 노드

  _Initialization에 대한EndMember 노드

NoiseMaker에 대한 EndObject

암시적 FavorCollection 항목 속성에 대한 EndMember 노드

암시적 FavorCollection에 대한 EndObject 노드

  </Party.Favors>

Favors에 대한 EndMember

</Party>

Party에 대한 EndObject

XAML 노드 스트림에서는 기본적으로 다음 동작이 적용됩니다.

  • Namespace 노드가 있는 경우 이 노드는 스트림에서 xmlns로 해당 XAML 네임스페이스를 선언한 StartObject 바로 앞에 추가됩니다. XAML과 예제 노드 스트림이 있는 위의 표를 다시 살펴봅시다. StartObject 및 Namespace 노드는 텍스트 태그에서 선언된 위치와 반대로 배치된 것처럼 보입니다. 이는 네임스페이스 노드가 노드 스트림에서 자신이 적용되는 노드 앞에 항상 나타나는 동작을 대표적으로 보여 줍니다. 이 디자인은 네임스페이스 정보가 개체 작성기에 필수적이므로 개체 작성기가 형식 매핑을 수행하거나 개체를 처리하기 전에 네임스페이스 정보를 알 수 있도록 하는 것입니다. 스트림에서 네임스페이스의 적용 범위 앞에 XAML 네임스페이스 정보를 배치하면 노드 스트림을 항상 표시된 순서대로 처리하는 것이 더 간단해집니다.

  • 위의 고려 사항 때문에 노드를 처음부터 트래버스할 때 대부분의 실제 태그 경우에 가장 먼저 읽는 것은 루트의 StartObject가 아니라 하나 이상의 Namespace 노드입니다.

  • StartObject 노드 뒤에는 StartMember 또는 Value가 오거나 EndObject가 바로 올 수 있습니다. 하지만 다른 StartObject가 바로 뒤에 표시되지는 않습니다.

  • StartMember 뒤에는 StartObject 또는 Value가 오거나 EndMember가 바로 올 수 있습니다. 부모 개체의 기존 값에서 값을 가져와야 하는 멤버의 경우에는 새 값을 인스턴스화하는 StartObject 대신 GetObject가 그 뒤에 올 수 있습니다. 또한 이후의 StartObject에 적용되는 Namespace 노드가 그 뒤에 올 수도 있습니다. 하지만 다른 StartMember가 바로 뒤에 표시되지는 않습니다.

  • Value 노드는 값 자체를 나타내며 "EndValue"가 없습니다. 이 노드 뒤에는 EndMember만 올 수 있습니다.

    • 생성에 사용될 수 있는 개체의 XAML 초기화 텍스트는 개체-값 구조를 만들지 않습니다. 대신 _Initialization이라는 멤버의 전용 멤버 노드가 만들어지고 이 멤버 노드에는 초기화 값 문자열이 포함됩니다. _Initialization은 존재하는 경우 항상 첫 번째 StartMember입니다. _Initialization은 일부 XAML 서비스 표현에서 XAML 언어 XAML 이름 범위를 사용하여 정규화되어 _Initialization이 지원 형식에서 정의된 속성이 아님을 명확히 나타낼 수 있습니다.

    • 멤버-값 조합은 값의 특성 설정을 나타냅니다. 이 값을 처리하는 데 결국 값 변환기가 관련될 수도 있으며 해당 값은 일반 문자열입니다. 그러나 이것은 XAML 개체 작성기가 이 노드 스트림을 처리할 때까지 확인되지 않습니다. XAML 개체 작성기는 필요한 XAML 스키마 컨텍스트, 형식 시스템 매핑 및 값 변환에 필요한 기타 지원 기능을 소유하고 있습니다.

  • EndMember 노드 뒤에는 이후 멤버에 대한 StartMember 노드나 멤버 소유자에 대한 EndObject 노드가 올 수 있습니다.

  • EndObject 노드 뒤에는 EndMember 노드가 표시될 수 있습니다. 개체가 컬렉션의 항목에서 피어인 경우에는 StartObject 노드가 뒤에 표시될 수도 있습니다. 또는 이후의 StartObject에 적용되는 Namespace 노드가 그 뒤에 올 수 있습니다.

    • 전체 노드 스트림을 닫는 고유한 경우에는 루트의 EndObject 뒤에는 아무 것도 표시되지 않습니다. 판독기가 이제 파일 끝이고 Read는 false를 반환합니다.

값 변환기 및 XAML 노드 스트림

값 변환기는 태그 확장, 형식 변환기(값 serializer 포함) 또는 XAML 형식 시스템을 통해 값 변환기로 보고되는 다른 전용 클래스에 대한 일반적인 용어입니다. XAML 노드 스트림에서 값 변환기 사용과 태그 확장 사용은 매우 다른 표현을 나타냅니다.

XAML 노드 스트림의 형식 변환기

최종적으로 형식 변환기가 사용되도록 하는 특성 집합은 XAML 노드 스트림에서 멤버의 값으로 보고됩니다. XAML 노드 스트림은 형식 변환기 인스턴스 개체를 생성하고 이 개체에 값을 전달하려고 하지 않습니다. 형식 변환기의 변환 구현을 사용하려면 XAML 스키마 컨텍스트를 호출하고 형식 매핑에 이를 사용해야 합니다. 값을 처리하는 데 사용해야 하는 형식 변환기 클래스를 결정하는 데도 XAML 스키마 컨텍스트가 간접적으로 필요합니다. 기본 XAML 스키마 컨텍스트를 사용하는 경우 XAML 형식 시스템에서 해당 정보를 사용할 수 있습니다. XAML 작성기에 연결하기 전에 XAML 노드 스트림 수준에서 형식 변환기 클래스 정보가 필요한 경우 설정될 멤버의 XamlMember 정보에서 해당 정보를 가져올 수 있습니다. 그렇지 않은 경우에는 XAML 개체 작성기에 의한 개체 생성과 같이 형식 매핑 시스템 및 XAML 스키마 컨텍스트가 필요한 나머지 작업이 수행될 때까지 형식 변환기 입력을 XAML 노드 스트림에 일반 값으로 유지해야 합니다.

예를 들어 다음 클래스 정의 개요와 이에 대한 XAML 사용을 살펴보겠습니다.

  public class BoardSizeConverter : TypeConverter {
    //converts from string to an int[2] by splitting on an "x" char
  }
  public class GameBoard {
    [TypeConverter(typeof(BoardSizeConverter))]
    public int[] BoardSize; //2x2 array, initialization not shown
  }
  <GameBoard BoardSize="8x8"/>

이 사용을 위한 XAML 노드 스트림의 텍스트 표현은 다음과 같이 표현될 수 있습니다.

GameBoard를 나타내는 XamlType이 있는 StartObject

BoardSize를 나타내는 XamlMember가 있는 StartMember

텍스트 문자열 "8x8"이 있는 Value 노드

EndMember는 BoardSize에 해당함

EndObject는 GameBoard에 해당함

이 노드 스트림에는 형식 변환기 인스턴스가 없습니다. 그러나 BoardSize에 대한 XamlMember에서 XamlMember.TypeConverter를 호출하여 형식 변환기 정보를 가져올 수 있습니다. 유효한 XAML 스키마 컨텍스트가 있는 경우 ConverterInstance에서 인스턴스를 가져와서 변환기 메서드를 호출할 수도 있습니다.

XAML 노드 스트림의 태그 확장

태그 확장 사용은 XAML 노드 스트림에서 멤버 내의 개체 노드로 보고됩니다. 여기서 개체는 태그 확장 인스턴스를 나타냅니다. 따라서 태그 확장 사용은 노드 스트림에서 표현에서 형식 변환기 사용보다 더 명시적으로 나타나며 더 많은 정보를 제공합니다. 태그 확장 사용이 상황에 따라 결정되고 가능한 각 태그 경우에서 달라지기 때문에 XamlMember 정보는 태그 확장에 대해 아무 것도 알려줄 수 없습니다. 태그 확장 사용은 형식 변환기의 경우처럼 형식이나 멤버별로 전용이거나 암시적이 아닙니다.

개체 노드로 나타낸 태그 확장의 노드 스트림 표현은 태그 확장 사용이 XAML 텍스트 태그에서 특성 형태로 만들어진 경우에도 해당됩니다(흔히 해당되는 경우임). 명시적 개체 요소 형태를 사용한 태그 확장 사용은 동일한 방식으로 처리됩니다.

태그 확장 개체 노드 내에는 해당 태그 확장의 멤버가 있을 수 있습니다. XAML 노드 스트림 표현은 위치 매개 변수 사용이든 명시적으로 명명된 매개 변수 사용이든 관계없이 해당 태그 확장의 사용을 보존합니다.

위치 매개 변수 사용을 위해 XAML 노드 스트림에는 XAML 언어에서 정의된 속성인 _PositionalParameters가 포함되어 있으며 이 속성이 태그 확장 사용을 기록합니다. 이 속성은 Object 제약 조건이 있는 제네릭 List<T>입니다. 위치 매개 변수 사용은 그 안에 중첩 태그 확장 사용을 포함할 수 있기 때문에 제약 조건은 개체이고 문자열이 아닙니다. 태그 확장 사용에서 위치 매개 변수에 액세스하려면 목록을 반복하고 개별 목록 값에 인덱서를 사용할 수 있습니다.

명명된 매개 변수 사용을 위해 명명된 각 매개 변수는 노드 스트림에서 해당 이름의 멤버 노드로 표현됩니다. 중첩 태그 확장 사용이 있을 수 있기 때문에 멤버 값은 문자열이 아닐 수도 있습니다.

태그 확장에서 ProvideValue는 아직 호출되지 않았습니다. 그러나 노드 스트림에서 ProvideValue를 검사할 때 태그 확장의 노드에서 WriteEndObject가 호출되도록 XAML 판독기와 XAML 작성기를 연결하면 ProvideValue가 호출됩니다. 이 때문에 로드 경로에서 개체 그래프를 형성하기 위해 사용하는 것처럼 일반적으로 동일한 XAML 스키마 컨텍스트를 사용할 수 있어야 합니다. 그렇지 않으면 태그 확장의 ProvideValue가 예상되는 서비스를 사용할 수 없기 때문에 여기에서 예외를 throw할 수 있습니다.

XAML 노드 스트림의 XAML 및 XML 언어에서 정의된 멤버

특정 멤버는 명시적 XamlMember 조회 또는 생성을 통해서가 아니라 XAML 판독기의 해석과 규칙 때문에 XAML 노드 스트림에 도입되었습니다. 이러한 멤버는 종종 XAML 지시문입니다. 일부 경우에는 XAML을 읽는 동작으로 인해 XAML 노드 스트림에 지시문이 도입됩니다. 즉, 원래 입력 XAML 텍스트는 멤버 지시문을 명시적으로 지정하지 않았지만 XAML 판독기가 XAML 구조 규칙을 충족하고 XAML 노드 스트림의 정보가 손실되기 전에 해당 정보를 보고하기 위해 지시문을 삽입합니다.

다음 목록에는 XAML 판독기가 지시문 XAML 멤버 노드를 도입해야 하는 모든 경우와 .NET Framework XAML 서비스 구현에서 해당 멤버 노드가 식별되는 방식이 나와 있습니다.

  • 개체 노드의 초기화 텍스트: 이 멤버 노드는 이름이 _Initialization이며, XAML 지시문을 나타내고 XAML 언어 XAML 네임스페이스에 정의되어 있습니다. Initialization에서 이 멤버의 정적 엔터티를 가져올 수 있습니다.

  • 태그 확장의 위치 매개 변수: 이 멤버 노드의 이름은 _PositionalParameters이며 XAML 언어 XAML 네임스페이스에 정의되어 있습니다. 이 멤버에는 항상 개체의 제네릭 목록이 포함되며, 이 목록의 각 항목은 입력 XAML에서 제공된 , 구분 기호에서 분리하여 미리 구분된 위치 매개 변수입니다. PositionalParameters에서 위치 매개 변수 지시문의 정적 엔터티를 가져올 수 있습니다.

  • 알 수 없는 콘텐츠: 이 멤버 노드의 이름은 _UnknownContent입니다. 엄격하게 말해서 이 멤버는 XamlDirective이며 XAML 언어 XAML 네임스페이스에 정의되어 있습니다. 이 지시문은 XAML 개체 요소가 소스 XAML에 콘텐츠를 포함하지만 현재 사용 가능한 XAML 스키마 컨텍스트에서 콘텐츠 속성을 확인할 수 없는 경우에 센티널로 사용됩니다. _UnknownContent라는 멤버를 확인하여 XAML 노드 스트림에서 이 경우를 검색할 수 있습니다. 로드 경로 XAML 노드 스트림에서 다른 작업을 수행하지 않는 경우 기본 XamlObjectWriter는 임의의 개체에서 _UnknownContent 멤버를 검색할 때 WriteEndObject가 시도되면 예외를 throw합니다. 기본 XamlXmlWriter는 예외를 throw하지 않고 멤버를 암시적 멤버로 처리합니다. UnknownContent에서 _UnknownContent의 정적 엔터티를 가져올 수 있습니다.

  • **컬렉션의 컬렉션 속성:**XAML에 사용되는 컬렉션 클래스의 지원 CLR 형식에는 일반적으로 컬렉션 항목을 포함하는 전용의 명명된 속성이 있지만 지원 형식이 확인되기 전에는 이 속성이 XAML 형식 시스템에 알려지지 않습니다. 대신 XAML 노드 스트림에서는 Items 자리 표시자를 컬렉션 XAML 형식의 멤버로 도입합니다. .NET Framework XAML 서비스 구현의 노드 스트림에서 이 지시문/멤버의 이름은 _Items입니다. 이 지시문의 상수는 Items에서 가져올 수 있습니다.

    XAML 노드 스트림에는 지원 형식 확인 및 XAML 스키마 컨텍스트에 따라 구문 분석할 수 없는 것으로 판명되는 항목과 함께 Items 속성이 포함될 수 있습니다. 다음 예제를 참조하십시오.

  • XML에서 정의된 멤버: XML에서 정의된 xml:base, xml:lang 및 xml:space 멤버는 .NET Framework XAML 서비스 구현에서 각각 base, lang 및 space라는 XAML 지시문으로 보고됩니다. 이러한 멤버의 네임스페이스는 XML 네임스페이스 http://www.w3.org/XML/1998/namespace입니다. 이러한 각 멤버의 상수는 XamlLanguage에서 가져올 수 있습니다.

노드 순서

일부 경우에 XamlXmlReader는 노드가 태그에 표시될 때 또는 XML로 처리될 때의 순서와 비교하여 XAML 노드 스트림의 XAML 노드 순서를 변경합니다. 이는 XamlObjectWriter가 앞으로만 이동 가능한 방식으로 노드 스트림을 처리할 수 있도록 노드를 정렬하기 위한 것입니다. .NET Framework XAML 서비스에서는 노드 스트림의 XAML 개체 작성기 소비자에 대한 성능 최적화의 일환으로 XAML 판독기가 노드를 다시 정렬하는 작업을 XAML 작성기에 맡기지 않고 직접 수행합니다.

일부 지시문은 특히 개체 요소에서 개체를 생성하는 데 필요한 추가 정보를 제공하기 위한 것입니다. 이러한 지시문은 Initialization, PositionalParameters, TypeArguments, FactoryMethod, Arguments입니다. .NET Framework XAML 서비스의 XAML 판독기는 이러한 지시문을 노드 스트림에서 개체의 StartObject 다음에 오는 첫 번째 멤버로 배치하려고 합니다. 그 이유는 다음 단원에서 설명합니다.

XamlObjectWriter 동작 및 노드 순서

XamlObjectWriter에 대한 StartObject는 반드시 XAML 개체 작성기에 개체 인스턴스를 즉시 생성하라고 보내는 신호인 것은 아닙니다. XAML에는 초기 개체를 생성한 다음 속성만 설정하는 기본 생성자를 호출하는 데 전적으로 의존하지 않고 추가 입력으로 개체를 초기화할 수 있도록 하는 몇 가지 언어 기능이 포함되어 있습니다. 이러한 기능으로는 XamlDeferLoadAttribute, 초기화 텍스트, x:TypeArguments, 태그 확장의 위치 매개 변수, 팩터리 메서드 및 관련 x:Arguments 노드가 있습니다(XAML 2009). 이러한 각 경우에는 실제 개체 생성이 지연됩니다. 노드 스트림이 다시 정렬되기 때문에 XAML 개체 작성기는 명시적으로 해당 개체 형식에 대한 생성 지시문이 아닌 시작 멤버가 나타날 때마다 인스턴스를 실제로 생성하는 동작에 의존할 수 있습니다.

GetObject

GetObject는 XAML 개체 작성기가 새 개체를 생성하는 대신 개체의 포함하는 속성에 대한 값을 가져와야 하는 XAML 노드를 나타냅니다. XAML 노드 스트림에서 GetObject노드는 일반적으로 포함하는 속성이 지원 형식의 개체 모델에서 의도적으로 읽기 전용일 때 컬렉션 개체 또는 사전 개체에 대해 나타납니다. 이 시나리오에서 컬렉션 또는 사전은 종종 소유하는 형식의 초기화 논리에 따라 만들어지고 초기화됩니다(일반적으로 빈 상태로)

참고 항목

참조

XamlObjectReader

개념

XAML 서비스

기타 리소스

.NET Framework XAML 서비스의 XAML 네임스페이스