WPF のツリーTrees in WPF

多くのテクノロジ要素とコンポーネントは、開発者は直接レンダリングや、アプリケーションの動作に影響を与える、ツリー内のオブジェクト ノード、操作をツリー構造で編成されています。In many technologies, elements and components are organized in a tree structure where developers directly manipulate the object nodes in the tree to affect the rendering or behavior of an application. Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) またプログラム要素間のリレーションシップを定義するのにいくつかのツリー構造のメタファを使用します。also uses several tree structure metaphors to define relationships between program elements. WPF 開発者の大部分できますコードでアプリケーションを作成または XAML で概念的には、オブジェクト ツリーの比喩を考えながら、アプリケーションの部分的な定義が、特定の API を呼び出すかをいくつかの一般的なのではなく、その特定のマークアップを使用する方法XML DOM で使用するなどのオブジェクトのツリー操作 APIFor the most part WPF developers can create an application in code or define portions of the application in XAML while thinking conceptually about the object tree metaphor, but will be calling specific API or using specific markup to do so rather than some general object tree manipulation API such as you might use in XML DOM. WPF のツリーの比喩ビューを提供する 2 つのヘルパー クラスが公開LogicalTreeHelperVisualTreeHelperします。WPF exposes two helper classes that provide a tree metaphor view, LogicalTreeHelper and VisualTreeHelper. 用語のビジュアル ツリーと論理ツリーも使用されます、WPF ドキュメントのため、同じようなツリーは特定のキーの WPF 機能の動作を理解するのに役立ちます。The terms visual tree and logical tree are also used in the WPF documentation because these same trees are useful for understanding the behavior of certain key WPF features. このトピックでは、ビジュアル ツリーと論理ツリーが表す内容を定義し、このようなツリーが、全体的なオブジェクトのツリーの概念に関連する方法について説明しますが導入されていますLogicalTreeHelperVisualTreeHelper秒。This topic defines what the visual tree and logical tree represent, discusses how such trees relate to an overall object tree concept, and introduces LogicalTreeHelper and VisualTreeHelpers.

WPF のツリーTrees in WPF

最も完全なツリー構造でWPFWPFはオブジェクトのツリーです。The most complete tree structure in WPFWPF is the object tree. アプリケーション ページを定義する場合XAMLXAMLし、ロード、 XAMLXAML、ツリー構造は、マークアップ内の要素の入れ子のリレーションシップに基づいて作成されます。If you define an application page in XAMLXAML and then load the XAMLXAML, the tree structure is created based on the nesting relationships of the elements in the markup. アプリケーションを定義するか、コードでは、アプリケーション、ツリー構造の一部が作成された場合は、特定のオブジェクトのコンテンツ モデルを実装するプロパティのプロパティ値を割り当てる方法に基づいています。If you define an application or a portion of the application in code, then the tree structure is created based on how you assign property values for properties that implement the content model for a given object. Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)は、完全なオブジェクトのツリーが概念化し、そのパブリック API に報告できます 2 つの方法があります: 論理ツリーとビジュアル ツリー。In Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF), there are two ways that the complete object tree is conceptualized and can be reported to its public API: as the logical tree and as the visual tree. 論理ツリーとビジュアル ツリー間の違いは、必ずしも、必ずしも重要なが特定の問題が発生することができる場合によっては、WPFWPFサブシステムとマークアップまたはコードで選択したに影響します。The distinctions between logical tree and visual tree are not always necessarily important, but they can occasionally cause issues with certain WPFWPF subsystems and affect choices you make in markup or code.

実行しない常に、論理ツリーまたはビジュアル ツリーを直接操作する場合でも、ツリーの操作方法の概念を理解するはテクノロジとして WPF を理解するために役立ちます。Even though you do not always manipulate either the logical tree or the visual tree directly, understanding the concepts of how the trees interact is useful for understanding WPF as a technology. 何らかの木のたとえはのプロパティの継承やイベントのルーティングのしくみを理解するために重要でも、WPF の検討WPFWPFします。Thinking of WPF as a tree metaphor of some kind is also crucial to understanding how property inheritance and event routing work in WPFWPF.

注意

オブジェクト ツリーより実際の API の概念の詳細は、概念と考えることを別の方法をオブジェクト グラフとしてです。Because the object tree is more of a concept than an actual API, another way to think of the concept is as an object graph. 実際には、ツリーの比喩が分割は、実行時のオブジェクト間のリレーションシップには。In practice, there are relationships between objects at run time where the tree metaphor will break down. ただし、特に UI の XAML 定義木のたとえは関連この一般的な概念を参照するときに、ほとんどの WPF のドキュメントがオブジェクト ツリーという用語を使用します。Nevertheless, particularly with XAML-defined UI, the tree metaphor is relevant enough that most WPF documentation will use the term object tree when referencing this general concept.

論理ツリーThe Logical Tree

WPFWPF、それらの要素のバックアップを作成するオブジェクトのプロパティを設定して UI 要素にコンテンツを追加します。In WPFWPF, you add content to UI elements by setting properties of the objects that back those elements. 項目を追加するなど、ListBoxコントロールを操作することによってそのItemsプロパティ。For example, you add items to a ListBox control by manipulating its Items property. これによりにアイテムを配置する、ItemCollectionつまり、Itemsプロパティの値。By doing this, you are placing items into the ItemCollection that is the Items property value. 同様に、追加するオブジェクトをDockPanel、操作するそのChildrenプロパティの値。Similarly, to add objects to a DockPanel, you manipulate its Children property value. ここでは、オブジェクトを追加する、UIElementCollectionします。Here, you are adding objects to the UIElementCollection. コード例では、次を参照してください。方法。要素を動的に追加します。For a code example, see How to: Add an Element Dynamically.

Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML)でリスト項目を配置するとき、 ListBox 、コントロール、または他の UI 要素で、 DockPanel、使用することも、ItemsChildrenプロパティ、明示的または暗黙的に、次の例のようにします。In Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML), when you place list items in a ListBox or controls or other UI elements in a DockPanel, you also use the Items and Children properties, either explicitly or implicitly, as in the following example.

<DockPanel
  Name="ParentElement"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
  <!--implicit: <DockPanel.Children>-->
  <ListBox DockPanel.Dock="Top">
    <!--implicit: <ListBox.Items>-->
    <ListBoxItem>
      <TextBlock>Dog</TextBlock>
    </ListBoxItem>
    <ListBoxItem>
      <TextBlock>Cat</TextBlock>
    </ListBoxItem>
    <ListBoxItem>
      <TextBlock>Fish</TextBlock>
    </ListBoxItem>
  <!--implicit: </ListBox.Items>-->
  </ListBox>
  <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>
  <!--implicit: </DockPanel.Children>-->
</DockPanel>

かどうかとして XML ドキュメント オブジェクト モデルでは、この XAML を処理したコメント タグが含まれていたかどうか、out 暗黙的な (これは有効でした)、結果の XML DOM ツリーに要素が含まれますが、<ListBox.Items>とその他の暗黙的な項目です。If you were to process this XAML as XML under a document object model, and if you had included the tags commented out as implicit (which would have been legal), then the resulting XML DOM tree would have included elements for <ListBox.Items> and the other implicit items. マークアップを読み取るオブジェクトを記述すると XAML がその方法を処理しませんは、生成されたオブジェクト グラフには文字どおりは含まれませんListBox.Itemsします。But XAML does not process that way when you read the markup and write to objects, the resulting object graph does not literally include ListBox.Items. ただしが、ListBoxという名前のプロパティItemsを格納している、 ItemCollection、およびItemCollectionは初期化されますが、空にする、 ListBox XAML が処理されます。It does however have a ListBox property named Items that contains a ItemCollection, and that ItemCollection is initialized but empty when the ListBox XAML is processed. 次に、各子オブジェクト要素のコンテンツとして存在する、ListBoxに追加されます、ItemCollectionパーサーを呼び出してItemCollection.Addします。Then, each child object element that exists as content for the ListBox is added to the ItemCollection by parser calls to ItemCollection.Add. この例のオブジェクト ツリーに XAML の処理はこれまでに一見例作成されたオブジェクト ツリーが論理ツリーでは基本的に。This example of processing XAML into an object tree is so far seemingly an example where the created object tree is basically the logical tree.

ただし、論理ツリーは、XAML の暗黙的な構文項目を使用しても、実行時に UI が除外されているアプリケーションに対して存在する全体オブジェクト グラフではありません。この主な理由は、ビジュアルとテンプレートです。However, the logical tree is not the entire object graph that exists for your application UI at run time, even with the XAML implicit syntax items factored out. The main reason for this is visuals and templates. たとえば、Buttonします。For example, consider the Button. 論理ツリー レポート、Buttonオブジェクトともその文字列Contentします。The logical tree reports the Button object and also its string Content. 実行時のオブジェクト ツリーで、このボタンにはたくさんあります。But there is more to this button in the run-time object tree. 具体的には、ボタンのみ画面に表示されるためはその方法は、特定のButtonコントロール テンプレートが適用されました。In particular, the button only appears on screen the way it does because a specific Button control template was applied. ビジュアル、適用されたテンプレートから取得した (テンプレートで定義されたなどBordervisual ボタンの周囲の濃い灰色の) 実行時に、論理ツリーが表示されている場合でも、論理ツリーでは報告されません (からの入力イベントの処理など、表示される UI とし、論理ツリーを読み取る)。The visuals that come from an applied template (such as the template-defined Border of dark gray around the visual button) are not reported in the logical tree, even if you are looking at the logical tree during run time (such as handling an input event from the visible UI and then reading the logical tree). テンプレートのビジュアルを検索するには、ビジュアル ツリーを調べるには代わりに必要です。To find the template visuals, you would instead need to examine the visual tree.

詳細についてXAMLXAML構文は、作成されたオブジェクトのグラフと、XAML で暗黙の型の構文を参照してくださいXAML 構文の詳細またはXAML の概要 (WPF)します。For more information about how XAMLXAML syntax maps to the created object graph, and implicit syntax in XAML, see XAML Syntax In Detail or XAML Overview (WPF).

論理ツリーの目的は、The Purpose of the Logical Tree

論理ツリーには、コンテンツ モデルは、使用可能な子オブジェクトを簡単に反復処理できるように、およびコンテンツ モデルの拡張が存在します。The logical tree exists so that content models can readily iterate over their possible child objects, and so that content models can be extensible. また、論理ツリー フレームワークを提供、特定の論理ツリー内のすべてのオブジェクトが読み込まれるタイミングなどの通知。Also, the logical tree provides a framework for certain notifications, such as when all objects in the logical tree are loaded. 基本的には、論理ツリーは、ビジュアルは含まれませんが、独自の実行時のアプリケーションの構成に対して多くのクエリ操作のための適切なフレームワーク レベルで実行時のオブジェクト グラフの概数です。Basically, the logical tree is an approximation of a run time object graph at the framework level, which excludes visuals, but is adequate for many querying operations against your own run time application's composition.

上の論理ツリーを検索して両方の静的および動的なリソースの参照を解決するさらに、Resources上、最初の要求オブジェクトと論理ツリーを続行し、各コレクションFrameworkElement(またはFrameworkContentElement)別のResources値を含む、 ResourceDictionary、そのキーを格納している可能性があります。In addition, both static and dynamic resource references are resolved by looking upwards through the logical tree for Resources collections on the initial requesting object, and then continuing up the logical tree and checking each FrameworkElement (or FrameworkContentElement) for another Resources value that contains a ResourceDictionary, possibly containing that key. 論理ツリーは、論理ツリーとビジュアル ツリーの両方が存在する場合、リソースの検索の使用されます。The logical tree is used for resource lookup when both the logical tree and the visual tree are present. リソース ディクショナリ、およびルックアップの詳細については、次を参照してください。 XAML リソースします。For more information on resource dictionaries and lookup, see XAML Resources.

論理ツリーのコンポジションComposition of the Logical Tree

論理ツリーが、WPF フレームワーク レベル、つまり論理ツリー操作にとって最も重要な WPF 基本要素はいずれかで定義されているFrameworkElementまたはFrameworkContentElementします。The logical tree is defined at the WPF framework-level, which means that the WPF base element that is most relevant for logical tree operations is either FrameworkElement or FrameworkContentElement. ただし、ことがわかります。 実際に使用場合、 LogicalTreeHelper API、論理ツリーもノードが含まれますどちらでもないFrameworkElementまたはFrameworkContentElementします。However, as you can see if you actually use the LogicalTreeHelper API, the logical tree sometimes contains nodes that are not either FrameworkElement or FrameworkContentElement. たとえば、論理ツリーを報告、Textの値をTextBlock文字列であります。For instance, the logical tree reports the Text value of a TextBlock, which is a string.

論理ツリーをオーバーライドします。Overriding the Logical Tree

高度なコントロールの作成者は、一般的なオブジェクトまたはコンテンツ モデルが追加または論理ツリー内のオブジェクトを削除する方法を定義するいくつかの Api をオーバーライドすることで、論理ツリーをオーバーライドできます。Advanced control authors can override the logical tree by overriding several APIs that define how a general object or content model adds or removes objects within the logical tree. 論理ツリーをオーバーライドする方法の例は、次を参照してください。論理ツリーをオーバーライドします。For an example of how to override the logical tree, see Override the Logical Tree.

プロパティ値の継承Property Value Inheritance

プロパティ値の継承は、ハイブリッド ツリーを通じて動作します。Property value inheritance operates through a hybrid tree. 実際のメタデータを含む、Inheritsプロパティの継承を有効にするプロパティは、WPF フレームワーク レベルFrameworkPropertyMetadataクラス。The actual metadata that contains the Inherits property that enables property inheritance is the WPF framework-level FrameworkPropertyMetadata class. そのため、元の値を保持する親とその値を継承する子オブジェクトの両方もなりませんFrameworkElementまたはFrameworkContentElement、必要がありますどちらもいくつかの論理ツリーの一部であるとします。Therefore, both the parent that holds the original value and the child object that inherits that value must both be FrameworkElement or FrameworkContentElement, and they must both be part of some logical tree. ただし、プロパティの継承をサポートする既存の WPF プロパティ、プロパティ値の継承は、論理ツリーに含まれていない間にあるオブジェクトを永続化することです。However, for existing WPF properties that support property inheritance, property value inheritance is able to perpetuate through an intervening object that is not in the logical tree. これは主には、継承されたプロパティの値は、テンプレート化されたインスタンスのいずれかの設定を使用して、テンプレート要素を含むもののまたはページ レベルの構成のも高いレベルでは関連があり、論理ツリー内の上位。Mainly this is relevant for having template elements use any inherited property values set either on the instance that is templated, or at still higher levels of page-level composition and therefore higher in the logical tree. プロパティ値の継承、このような境界を越えて一貫して動作するためには、継承プロパティは、添付プロパティとして登録する必要があり。、カスタム依存関係プロパティとプロパティを定義する場合、このパターンに従う必要があります。継承の動作です。In order for property value inheritance to work consistently across such a boundary, the inheriting property must be registered as an attached property, and you should follow this pattern if you intend to define a custom dependency property with property inheritance behavior. プロパティの継承に使用される正確なツリーは、実行時にもヘルパー クラスのユーティリティ メソッドがまったく予期することはできません。The exact tree used for property inheritance cannot be entirely anticipated by a helper class utility method, even at run time. 詳細については、「プロパティ値の継承」を参照してください。For more information, see Property Value Inheritance.

ビジュアル ツリーThe Visual Tree

だけでなく、論理ツリーの概念も、概念は、ビジュアル ツリー内のWPFWPFします。In addition to the concept of the logical tree, there is also the concept of the visual tree in WPFWPF. によって表されるビジュアル ツリーは、ビジュアル オブジェクトの構造について説明します、Visual基本クラス。The visual tree describes the structure of visual objects, as represented by the Visual base class. コントロールのテンプレートを記述するときにを定義するか、そのコントロールに適用するビジュアル ツリーを再定義ができます。When you write a template for a control, you are defining or redefining the visual tree that applies for that control. ビジュアル ツリーは、パフォーマンスおよび最適化のために、描画に対して低レベルの制御を望む開発者にとって重要なのもです。The visual tree is also of interest to developers who want lower-level control over drawing for performance and optimization reasons. 従来の一部として、ビジュアル ツリーの 1 つの露出WPFWPFアプリケーション プログラミングは、ルーティング イベントのイベント ルートはほとんどの場合、論理ツリーではなく、ビジュアル ツリーに沿って伝達されます。One exposure of the visual tree as part of conventional WPFWPF application programming is that event routes for a routed event mostly travel along the visual tree, not the logical tree. コントロールの作成者でない限り、ルーティング イベントの動作の細部をすぐにわかりますできない可能性があります。This subtlety of routed event behavior might not be immediately apparent unless you are a control author. ビジュアル ツリーを介したイベントのルーティングには、イベントを処理したり、イベント setter を作成するビジュアル レベルで構成を実装するコントロールができます。Routing events through the visual tree enables controls that implement composition at the visual level to handle events or create event setters.

ツリー、コンテンツ要素、およびコンテンツのホストTrees, Content Elements, and Content Hosts

要素のコンテンツ (クラスから派生したContentElement)、ビジュアル ツリーの一部ではない; から継承しないVisual視覚的に表現はありません。Content elements (classes that derive from ContentElement) are not part of the visual tree; they do not inherit from Visual and do not have a visual representation. すべての UI に表示するには、ContentElement両方にあるコンテンツのホストでホストする必要があります、Visualおよび論理ツリーの参加要素。In order to appear in a UI at all, a ContentElement must be hosted in a content host that is both a Visual and a logical tree participant. このようなオブジェクトは、通常、FrameworkElementします。Usually such an object is a FrameworkElement. コンテンツのホストは、コンテンツが、"browser"のようなものと、ホストを制御する画面領域内でそのコンテンツを表示する方法を選択を考えることができます。You can conceptualize that the content host is somewhat like a "browser" for the content and chooses how to display that content within the screen region that the host controls. コンテンツがホストされている場合、コンテンツは通常、ビジュアル ツリーに関連付けられている特定のツリー プロセスに参加要素を作成できます。When the content is hosted, the content can be made a participant in certain tree processes that are normally associated with the visual tree. 一般に、FrameworkElementホスト クラスには、ホストされているいずれかを追加する実装コードが含まれています。ContentElementコンテンツの論理ツリーのサブノードをイベントのルーティングに場合でもホストされたコンテンツが true のビジュアル ツリーの一部です。Generally, the FrameworkElement host class includes implementation code that adds any hosted ContentElement to the event route through subnodes of the content logical tree, even though the hosted content is not part of the true visual tree. これは、必要なように、ContentElement自体以外の任意の要素にルーティングするルーティング イベント ソースのことができます。This is necessary so that a ContentElement can source a routed event that routes to any element other than itself.

ツリーの走査Tree Traversal

LogicalTreeHelperクラスには、 GetChildrenGetParent、およびFindLogicalNode論理ツリーの走査のためのメソッド。The LogicalTreeHelper class provides the GetChildren, GetParent, and FindLogicalNode methods for logical tree traversal. ほとんどの場合必要はありません、既存のコントロールの論理ツリーを走査するため、これらのコントロールはなどコレクションへのアクセスをサポートする専用のコレクション プロパティとして、論理上の子要素を公開するほとんどの場合にAddインデクサー、などなど。In most cases, you should not have to traverse the logical tree of existing controls, because these controls almost always expose their logical child elements as a dedicated collection property that supports collection access such as Add, an indexer, and so on. ツリーの走査は主にシナリオなど、目的のコントロール パターンから派生しないように選択コントロールの作成者によって使用されるItemsControlまたはPanelコレクションのプロパティが既に定義されていると、独自のコレクションを使用するユーザープロパティのサポート。Tree traversal is mainly a scenario that is used by control authors who choose not to derive from intended control patterns such as ItemsControl or Panel where collection properties are already defined, and who intend to provide their own collection property support.

ビジュアル ツリーの走査のビジュアル ツリーがヘルパー クラスにもサポートしていますVisualTreeHelperします。The visual tree also supports a helper class for visual tree traversal, VisualTreeHelper. コントロール固有のプロパティで、ビジュアル ツリーとして簡単に公開されないため、VisualTreeHelperクラスは、プログラミングのシナリオのために必要な場合に、ビジュアル ツリーを走査するをお勧めします。The visual tree is not exposed as conveniently through control-specific properties, so the VisualTreeHelper class is the recommended way to traverse the visual tree if that is necessary for your programming scenario. 詳しくは、「WPF グラフィックス レンダリングの概要」をご覧ください。For more information, see WPF Graphics Rendering Overview.

注意

適用されたテンプレートのビジュアル ツリーを調べる必要があります。Sometimes it is necessary to examine the visual tree of an applied template. この手法を使用する場合は注意する必要があります。You should be careful when using this technique. コントロールのビジュアル ツリーを走査し、テンプレートを定義するが、場合でも、コントロールのコンシューマー常に、テンプレート設定を変更できます、Templateインスタンス、およびエンド ユーザーでもプロパティが変更することでテンプレートを適用したを与えることができます、システムのテーマ。Even if you are traversing a visual tree for a control where you define the template, consumers of your control can always change the template by setting the Template property on instances, and even the end user can influence the applied template by changing the system theme.

ルーティング イベントとして「ツリー」のルートRoutes for Routed Events as a "Tree"

前述のように、特定のルーティング イベントのルートはビジュアルと論理ツリー表現を組み合わせるハイブリッドであるツリーの 1 つと事前に定義されたパスに沿って移動します。As mentioned before, the route of any given routed event travels along a single and predetermined path of a tree that is a hybrid of the visual and logical tree representations. イベントのルーティングが最大でいずれかに移動または、方向がかどうかに応じて、ツリー内をトンネリングやバブル ルーティング イベント。The event route can travel either in the up or down directions within the tree depending on whether it is a tunneling or bubbling routed event. イベント ルートの概念には、「説明」実際にルーティングするイベントを発生させるとは別にイベントのルーティングに使用できるヘルパー クラスを直接サポートはありません。The event route concept does not have a directly supporting helper class that could be used to "walk" the event route independently of raising an event that actually routes. ルートを表すクラスがあるEventRoute、そのクラスのメソッドは、通常、内部使用のみが、します。There is a class that represents the route, EventRoute, but the methods of that class are generally for internal use only.

リソース ディクショナリとツリーResource Dictionaries and Trees

すべてのリソース ディクショナリのルックアップResources定義ページに基本的に、論理はツリーを走査します。Resource dictionary lookup for all Resources defined in a page traverses basically the logical tree. 論理ツリーに含まれていないオブジェクトがキーを持つリソースを参照できますが、論理ツリーにそのオブジェクトが接続されているポイントではリソース参照シーケンスが開始されます。Objects that are not in the logical tree can reference keyed resources, but the resource lookup sequence begins at the point where that object is connected to the logical tree. WPF では、論理ツリーのノードのみを持つことができます、Resourcesプロパティを含む、 ResourceDictionary、したがってからキーを持つリソースを探して、ビジュアル ツリーの走査の利点はありません、ResourceDictionaryします。In WPF, only logical tree nodes can have a Resources property that contains a ResourceDictionary, therefore there is no benefit in traversing the visual tree looking for keyed resources from a ResourceDictionary.

ただし、リソースの検索も、直接の論理ツリーを超えて拡張できます。However, resource lookup can also extend beyond the immediate logical tree. アプリケーション マークアップでは、アプリケーション レベルのリソース ディクショナリ、静的プロパティまたはキーとして参照されているテーマのサポート、およびシステム値へとリソース検索が続きます。For application markup, the resource lookup can then continue onward to application-level resource dictionaries and then to theme support and system values that are referenced as static properties or keys. テーマ自体は、動的リソース参照である場合、テーマの論理ツリーの外部システムの値を参照できます。Themes themselves can also reference system values outside of the theme logical tree if the resource references are dynamic. リソース ディクショナリとルックアップ ロジックの詳細については、次を参照してください。 XAML リソースします。For more information on resource dictionaries and the lookup logic, see XAML Resources.

関連項目See also