다음을 통해 공유


WPF의 트리

업데이트: 2007년 11월

많은 기술에서 요소와 구성 요소는 트리 구조로 구성되며 개발자는 이 트리를 직접 조작하여 응용 프로그램의 렌더링에 영향을 줍니다. WPF(Windows Presentation Foundation)에서도 여러 가지 트리 구조 비유를 통해 프로그램 요소 간의 관계를 정의합니다.

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

  • WPF의 트리
  • 논리적 트리
  • 시각적 트리
  • 트리, 콘텐츠 요소 및 콘텐츠 호스트
  • 트리 이동
  • 라우트된 이벤트의 경로("트리")
  • 리소스 및 트리
  • 관련 항목

WPF의 트리

WPF의 기본 트리 구조는 요소 트리입니다. XAML로 응용 프로그램 페이지를 만들면 태그 내 요소의 중첩 관계를 기반으로 트리 구조가 만들어집니다. 코드로 응용 프로그램을 만들면 지정된 요소에 대한 콘텐츠 모델을 구현하는 속성에 속성 값을 할당한 방법을 기준으로 트리 구조가 만들어집니다. WPF(Windows Presentation Foundation)에서는 논리적 트리와 시각적 트리라는 두 가지 방법으로 요소 트리를 처리하고 개념화합니다. 논리적 트리와 시각적 트리의 차이가 항상 중요한 것은 아니지만 특정 WPF 하위 시스템에서는 종종 문제를 일으킬 수 있으며 사용자가 태그나 코드에서 선택하는 항목에 영향을 줄 수 있습니다.

논리적 트리나 시각적 트리를 항상 직접 조작하지는 않더라도 두 트리 개념이 어떻게 상호 작용하는지 알고 있으면 WPF에서의 속성 상속 및 이벤트 라우팅의 작동 원리를 보다 쉽게 이해할 수 있습니다.

논리적 트리

WPF에서는 속성을 사용하여 요소에 콘텐츠를 추가합니다. 예를 들어 ListBox 컨트롤에 항목을 추가할 때는 해당 Items 속성을 사용합니다. 이렇게 하여 ListBox 컨트롤의 ItemCollection에 항목을 배치할 수 있습니다. DockPanel에 요소를 추가할 때는 해당 Children 속성을 사용합니다. 이때는 DockPanelUIElementCollection에 요소를 추가하게 됩니다. 코드 예제를 보려면 방법: 동적으로 요소 추가를 참조하십시오.

XAML(Extensible Application Markup Language)에서 ListBox의 목록 항목, 컨트롤 또는 다른 요소를 DockPanel에 배치할 때는 다음 예제와 같이 명시적 또는 암시적으로 ItemsChildren 속성도 사용합니다.

<DockPanel
  Name="ParentElement"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >

  <!--implicit: <DockPanel.Children>-->
  <ListBox DockPanel.Dock="Top">
    <!--implicit: <ListBox.Items>-->
    <ListItem>
      <Paragraph>Dog</Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>Cat</Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>Fish</Paragraph>
    </ListItem>
    <!--implicit: </ListBox.Items>-->
  </ListBox>
  <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>

  <!--implicit: </DockPanel.Children>-->
</DockPanel>

XAML 판독기는 응용 프로그램 실행 파일의 런타임 개체 표현을 만들 때 속성 요소를 유추하므로 속성 요소 태그가 명시적으로 필요하지는 않습니다. XAML 구문이 생성된 논리적 트리에 매핑되는 방법 및 유추된 태그에 대한 자세한 내용은 XAML 구문 용어 또는 XAML 개요를 참조하십시오. 다음 그래픽에서는 런타임에 생성된 논리적 트리를 개념적으로 보여 줍니다. 단추의 분기는 그래픽에 표시되어 있지 않습니다.

일반 논리적 트리의 구성도

트리 다이어그램

논리적 트리의 용도

논리적 트리는 콘텐츠 모델이 해당 자식 요소에서 쉽게 반복될 수 있도록 하고 콘텐츠 모델을 확장할 수 있도록 하는 역할을 합니다. 또한 논리적 트리는 논리적 트리의 모든 요소가 로드되었을 때와 같은 특정 알림을 위한 프레임워크를 제공합니다.

뿐만 아니라 초기 요청 요소에서 시작하여 부모 요소의 순으로 논리적 트리의 위쪽으로 Resources 컬렉션을 찾아 리소스 참조를 확인할 수도 있습니다. 논리적 트리와 시각적 트리가 모두 있는 경우 리소스 조회 시 논리적 트리가 사용됩니다. 리소스에 대한 자세한 내용은 리소스 개요를 참조하십시오.

논리적 트리 재정의

고급 컨트롤 작성자는 일반 개체 또는 콘텐츠 모델이 논리적 트리 내에서 요소를 추가하거나 제거하는 방법을 정의하는 몇 가지 API를 재정의하여 논리적 트리를 재정의할 수 있습니다. 논리적 트리를 재정의하는 방법을 보여 주는 예제는 방법: 논리 트리 재정의를 참조하십시오.

속성 값 상속

속성 값 상속은 혼합 트리를 통해 작동합니다. 속성 상속을 가능하게 하는 Inherits 속성을 포함하는 실제 메타데이터는 WPF 프레임워크 수준 FrameworkPropertyMetadata 클래스입니다. 따라서 원래 값을 보유하는 부모와 해당 값을 상속하는 자식 요소는 모두 FrameworkElement 또는 FrameworkContentElement여야 하고 논리적 트리의 일부여야 합니다. 하지만 속성 값 상속은 논리적 트리에 없는 중간의 시각적 요소에도 적용되므로 부모와 자식의 논리적 트리가 결합되어 있지 않아도 됩니다. 이러한 경계에서 속성 값이 일관되게 상속되려면 상속 속성이 연결된 속성으로 등록되어 있어야 합니다. 속성 상속에 사용되는 트리가 어떤 것인지는 도우미 클래스 유틸리티 메서드가 정확하게 예상할 수 없으며 이는 런타임에도 마찬가지입니다. 자세한 내용은 속성 값 상속을 참조하십시오.

시각적 트리

WPF에는 논리적 트리라는 개념과 함께 시각적 트리라는 개념도 사용됩니다. 시각적 트리는 Visual 기본 클래스가 나타내는 시각적 요소의 구조를 설명합니다. 컨트롤의 템플릿을 작성할 때 컨트롤에 적용되는 시각적 트리를 정의하거나 다시 정의합니다. 시각적 트리는 성능 및 최적화를 위해 그리기에 하위 수준의 컨트롤을 사용하려는 개발자에게도 유용합니다. 시각적 트리가 기본 WPF 응용 프로그램 프로그래밍의 일부로 노출되는 한 가지 예로 라우트된 이벤트의 이벤트 경로가 대부분 논리적 트리가 아니라 시각적 트리를 따라 이동하는 것을 들 수 있습니다. 라우트된 이벤트의 이와 같은 미묘한 동작은 컨트롤 작성자가 아니면 쉽게 알지 못할 수 있습니다. 시각적 트리 라우팅 덕분에 시각적 수준에서 컴퍼지션을 구현하는 컨트롤이 이벤트를 처리하거나 이벤트 setter를 만들 수 있습니다.

트리, 콘텐츠 요소 및 콘텐츠 호스트

콘텐츠 요소(ContentElement에서 파생되는 클래스)는 시각적 트리의 일부가 아닙니다. 콘텐츠 요소는 Visual에서 상속되지 않으므로 시각적 표현이 없습니다. ContentElement가 UI에 나타나려면 Visual이면서 동시에 논리적 트리 요소(대개의 경우 FrameworkElement)인 콘텐츠 호스트에서 호스팅되어야 합니다. 콘텐츠 호스트는 호스트가 제어하는 화면 영역 내에서 콘텐츠 표시 방법을 선택하는 콘텐츠용 "브라우저"라고 볼 수 있습니다. 콘텐츠가 호스팅되면 일반적으로 시각적 트리와 연결된 특정 트리 프로세스에 참가하도록 콘텐츠를 설정할 수 있습니다. 일반적으로 FrameworkElement 호스트 클래스에는 호스팅된 콘텐츠가 실제 시각적 트리의 일부가 아닌 경우를 비롯하여 호스팅된 ContentElement를 콘텐츠 논리적 트리의 하위 노드를 통해 이벤트 경로에 추가하는 구현 코드가 포함되어 있습니다. 이렇게 해야만 ContentElement가 자신이 아닌 다른 요소로 이동하는 라우트된 이벤트를 발생시킬 수 있습니다.

트리 이동

LogicalTreeHelper 클래스는 논리적 트리 이동을 위해 GetChildren, GetParentFindLogicalNode 메서드를 제공합니다. 대부분의 경우 기존 컨트롤은 자신의 논리적 자식 요소를 항상 Add, 인덱서 등의 컬렉션 API를 지원하는 전용 컬렉션 속성으로 노출하므로 기존 컨트롤의 논리적 트리는 이동하지 않아야 합니다. 트리 이동은 ItemsControl 또는 Panel과 같이 컬렉션 속성이 이미 정의된 컨트롤 패턴에서 파생하지 않고 자체적인 컬렉션 속성 지원을 제공하려는 컨트롤 작성자가 주로 사용하는 시나리오입니다.

시각적 트리도 시각적 트리 이동을 위해 VisualTreeHelper라는 도우미 클래스를 지원합니다. 시각적 트리는 컨트롤별 속성을 통해 노출되지 않습니다. 따라서 프로그래밍 시나리오에 필요하여 시각적 트리를 이동해야 하는 경우에는 VisualTreeHelper 클래스를 사용하는 것이 좋습니다. 자세한 내용은 Windows Presentation Foundation 그래픽 렌더링 개요를 참조하십시오.

라우트된 이벤트의 경로("트리")

앞에서 설명한 것과 같이 라우트된 이벤트의 경로는 이벤트가 터널링 라우트된 이벤트인지 또는 버블링 라우트된 이벤트인지에 따라 트리에서 위쪽 또는 아래쪽으로 효과적으로 이동합니다. 이벤트 경로라는 개념에는 실제로 경로를 이동하는 이벤트의 발생과는 독립적으로 이벤트 경로를 "단계별로 이동"하는 데 사용할 수 있는 직접적인 지원 도우미 클래스가 없습니다. 경로를 나타내는 EventRoute라는 클래스는 있지만 이 클래스의 메서드는 일반적으로 내부 전용입니다.

리소스 및 트리

리소스를 조회할 때는 기본적으로 논리적 트리를 이동합니다. 논리적 트리에 없는 개체가 리소스를 참조할 수는 있습니다. 하지만 조회가 시작되는 위치는 개체와 논리적 트리가 연결되는 지점입니다. 논리적 트리 노드만 ResourceDictionary가 포함된 Resources 속성을 가질 수 있으므로 리소스를 조회하기 위해 시각적 트리를 이동하는 것은 아무런 의미가 없습니다.

하지만 리소스 조회의 범위를 직접적 논리적 트리를 넘어 확장할 수 있습니다. 응용 프로그램 태그의 경우 논리적 트리를 조회한 후 계속해서 응용 프로그램 리소스와 테마 지원 및 시스템 값을 조회할 수 있습니다. 리소스 참조가 동적인 경우 테마도 테마의 논리적 트리 외부에 있는 시스템 값을 참조할 수 있습니다. 리소스 및 조회 논리에 대한 자세한 내용은 리소스 개요를 참조하십시오.

참고 항목

개념

입력 개요

Windows Presentation Foundation 그래픽 렌더링 개요

라우트된 이벤트 개요

요소 트리에 없는 개체 요소 초기화

WPF 아키텍처