Share via


WPF 中的樹狀結構

更新:2007 年 11 月

在許多技術中,項目和元件都會組織成樹狀結構,開發人員可直接操作樹狀結構來影響應用程式的轉譯。Windows Presentation Foundation (WPF) 也使用數個樹狀結構來定義程式項目間的關係。

這個主題包含下列章節。

  • WPF 中的樹狀結構
  • 邏輯樹狀結構
  • 視覺化樹狀結構
  • 樹狀結構、內容項目和內容裝載
  • 樹狀結構周遊
  • 路由事件的樹狀結構路由
  • 資源和樹狀結構
  • 相關主題

WPF 中的樹狀結構

WPF 中的主要樹狀結構就是項目樹狀結構。如果您在 XAML 中建立應用程式頁面,會根據標記中項目的巢狀關係來建立項目樹狀結構。如果您是在程式碼中建立應用程式,則會根據用來實作項目內容模型的屬性值來建立項目樹狀結構。在 Windows Presentation Foundation (WPF) 中,項目樹狀結構會以兩種方式處理和概念化:邏輯樹狀結構和視覺化樹狀結構。邏輯樹狀結構與視覺化樹狀結構的差異並不一定都很重要,但有時可能會導致 WPF 某些子系統發生問題,並在您使用標記或程式碼編寫程式時影響您的選擇。

即使您不一定會直接操作邏輯樹狀結構或視覺化樹狀結構,了解這些樹狀結構如何互動,將有助於了解 WPF 中屬性如何繼承和事件路由的方式。

邏輯樹狀結構

在 WPF 中,您可以使用屬性將內容加入到項目 (Element)。例如,您可以使用 Items 屬性,將項目 (Item) 加入到 ListBox 控制項。這麼做是將項目 (Item) 置於 ListBox 控制項的 ItemCollection。若要將項目 (Element) 加入到 DockPanel,您可以使用其 Children 屬性。在此例中,您是將項目 (Element) 加入到 DockPanelUIElementCollection。如需程式碼範例,請參閱 HOW TO:以動態方式加入項目

在可延伸標記語言 (XAML) 中,當您將清單項目 (Item) 置於 ListBox,或將控制項或其他項目 (Element) 置於 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>

請注意,並非明確需要屬性項目 (Element) 標記,因為 XAML 讀取器在建立物件以建立可執行檔的應用程式執行階段物件表示時,會推斷屬性項目。如需 XAML 語法如何對應到已建立之邏輯樹狀結構的詳細資訊,請參閱 XAML 語法術語XAML 概觀。下圖提供執行階段建構之邏輯樹狀結構的概念性檢視 (圖中省略按鈕的分支)。

泛型邏輯樹狀結構圖解

樹狀架構圖表

邏輯樹狀結構的用途

邏輯樹狀結構的存在,是要讓內容模型可立即逐一查看其可能的子項目,並使內容模型得以延伸。再者,邏輯樹狀結構也可提供進行某些通知的架構,例如當邏輯樹狀結構中的所有項目都載入完畢時。

此外,資源參考也可進行解析,方式是在 Resources 集合的邏輯樹狀結構中向上查閱初始要求的子項目,然後再查閱父項目。當邏輯樹狀結構和視覺化樹狀結構同時存在時,資源查閱作業會使用邏輯樹狀結構。如需資源的詳細資訊,請參閱資源概觀

覆寫邏輯樹狀結構

若您是資深控制項作者,可覆寫數個用來定義一般物件或內容模型如何在邏輯樹狀結構內加入或移除項目的 API,來覆寫邏輯樹狀結構。如需如何覆寫邏輯樹狀結構的範例,請參閱 HOW TO:覆寫邏輯樹狀結構

屬性值繼承

屬性值繼承作業會透過混合樹狀結構進行。包含啟用屬性繼承之 Inherits 屬性的實際中繼資料,就是 WPF 架構層級  FrameworkPropertyMetadata 類別。因此,存放原始值的父項目和繼承的子項目必須都是 FrameworkElementFrameworkContentElement,而且必須都屬於某個邏輯樹狀結構的一部分。不過,父項目和子項目的邏輯樹狀結構可以分開,透過是介入性質但不在邏輯樹狀結構的視覺化項目,屬性值繼承便可以永遠存在。為使屬性值繼承能夠跨界限一致地運作,繼承的屬性必須註冊為附加屬性。Helper 類別公用程式方法完全無法預期屬性繼承所使用的樹狀結構,即使在執行階段也一樣。如需詳細資訊,請參閱屬性值繼承

視覺化樹狀結構

除了邏輯樹狀結構的概念,WPF 中還有視覺化樹狀結構的概念。視覺化樹狀結構會描述 Visual 基底類別所表示之視覺化項目的結構。當您撰寫控制項的樣板時,就是在定義或重新定義適用於該控制項的視覺化樹狀結構。視覺化樹狀結構也可讓開發人員對繪製作業採取低階控制,以改善效能和進行最佳化。通常 WPF 應用程式在開發時,公開視覺樹的方式之一,就是路由事件的事件在路由時大多沿著視覺化樹狀結構前進,而非邏輯樹狀結構。除非是控制項作者,否則並不容易立即察覺到此路由事件行為的細微差別。透過視覺化樹狀結構進行路由,讓在視覺化層級中實作組合的控制項,可以處理事件或建立事件設定者 (Setter)。

樹狀結構、內容項目和內容裝載

內容項目 (衍生自 ContentElement 的類別) 不屬於視覺化樹狀結構的一部分,它們不是繼承自 Visual,也沒有視覺化表示。為能出現在 UI 中,ContentElement 必須裝載於同時是 Visual 和邏輯樹狀結構項目的內容裝載 (Content Host),這通常是 FrameworkElement。您可以將內容裝載想像成內容的「瀏覽器」,並選擇該內容要如何顯示在裝載著控制項的螢幕區域內。當裝載好內容時,該內容就可以成為某些樹狀結構處理序 (通常與視覺化樹狀結構相關聯) 中的參與者。一般而言,FrameworkElement 裝載類別包含實作程式碼,此實作程式碼會透過內容邏輯樹狀結構的子節點,將任何裝載的 ContentElement 加入到事件路由,即使裝載的內容不屬於實際視覺化樹狀結構的一部分。這是必要的,ContentElement 才能獲得路由至本身以外任何項目的路由事件。

樹狀結構周遊

LogicalTreeHelper 類別提供 GetChildrenGetParentFindLogicalNode 方法來周遊邏輯樹狀結構。大部分情況下,您應該不需要周遊現有控制項的邏輯樹狀結構,因為這些控制項幾乎都會將其邏輯子項目公開為專屬的集合屬性,以支援集合 API,例如 Add、索引子等。樹狀結構周遊功能主要適用於兩種控制項作者使用:選擇不從適用的控制項模式衍生 (例如 ItemsControlPanel 等已經定義集合屬性) 的控制項作者,或者想要提供自己之集合屬性支援的控制項作者。

視覺化樹狀結構也支援進行視覺化樹狀結構周遊的 Helper 類別 VisualTreeHelper。由於視覺化樹狀結構無法方便地透過控制項特定屬性公開,如在程式設計時有必要,建議使用 VisualTreeHelper 類別周遊視覺化樹狀結構。如需詳細資訊,請參閱 Windows Presentation Foundation 圖形轉譯概觀

路由事件的樹狀結構路由

如前所述,路由事件的路由實際上就是沿著樹狀結構前進,視其為通道 (Tunneling) 或反昇 (Bubbling) 路由事件而定,會在樹狀結構中向上或向下行進。事件路由概念沒有直接支援的 Helper 類別可供在事件路由上「前進」,而不管是否引發實際路由的事件。有個類別可代表路徑:EventRoute,但此類別的方法一般僅供內部使用。

資源和樹狀結構

資源查閱基本上是周遊邏輯樹狀結構。不在邏輯樹狀結構的物件可以參考資源,但查閱是從物件連接到邏輯樹狀結構的點開始。只有邏輯樹狀結構節點才能有包含 ResourceDictionary 的 Resources 屬性,這表示周遊視覺化樹狀結構來尋找資源並無任何好處。

不過,資源查閱也可延伸至目前邏輯樹狀結構以外的地方。若為應用程式標記,資源查閱可繼續尋找應用程式資源以及佈景主題支援和系統值。如果資源參考是動態的,則佈景主題本身也可以參考佈景主題邏輯樹狀結構以外的系統值。如需資源和查閱邏輯的詳細資訊,請參閱資源概觀

請參閱

概念

輸入概觀

Windows Presentation Foundation 圖形轉譯概觀

路由事件概觀

初始化項目樹狀結構以外的物件項目

WPF 架構