架構屬性中繼資料
更新:2007 年 11 月
若系統認為物件項目的屬性位於 Windows Presentation Foundation (WPF) 架構 (Architecture) 中的 WPF 架構層級 (WPF Framework Level),便會針對這些屬性回報架構 (Framework) 屬性中繼資料 (Metadata) 選項。WPF 架構階層的指定通常代表諸如呈現、資料繫結 (Data Binding) 和屬性系統更新等功能,都是由 WPF 展示 API 和可執行檔負責處理。這些系統會查詢架構屬性中繼資料,以判斷特定項目屬性的功能相關特性。
這個主題包含下列章節。
- 必要條件
- 架構屬性中繼資料傳達的資訊
- 讀取 FrameworkPropertyMetadata
- 指定中繼資料
- 架構屬性中繼資料合併行為
- 相關主題
必要條件
本主題假設您已了解相依性屬性,知道如何使用 Windows Presentation Foundation (WPF) 類別上的現有相依性屬性,而且也閱讀過相依性屬性概觀。另外,您也應該已經閱讀過相依性屬性中繼資料。
架構屬性中繼資料傳達的資訊
架構屬性中繼資料可分成下列幾種類別:
影響項目的報告配置屬性 (AffectsArrange、AffectsMeasure、AffectsRender)。如果屬性分別影響這些設定,而且您也正在類別中實作 MeasureOverride / ArrangeOverride 方法以提供特定呈現行為和資訊給配置系統,您可以在中繼資料中設定這些旗標。這類實作通常會在屬性中繼資料中這些配置屬性為 true 的相依性屬性中,檢查屬性是否失效,而且只有這些失效屬性需要要求新的配置傳遞。
影響項目之父項目的報告配置屬性 (AffectsParentArrange、AffectsParentMeasure)。預設設定這些旗標的範例包括 FixedPage.Left 和 Paragraph.KeepWithNext。
Inherits。根據預設,相依性屬性不會繼承值。OverridesInheritanceBehavior 也容許繼承 (Inheritance) 路徑進入視覺化樹狀結構,而這在某些控制項複合 (Compositing) 案例中是必要的。
注意事項: 「繼承」一詞在屬性值的內容中代表相依性屬性專用的特性,其表示由於 WPF 屬性系統的 WPF 架構層級功能,使得子項目可以從父項目繼承實際的相依屬性值。它和 Managed 程式碼型別以及透過衍生型別 (Derived Type) 的成員繼承並無任何直接關聯。如需詳細資訊,請參閱屬性值繼承。
報告資料繫結特性 (IsNotDataBindable、BindsTwoWayByDefault)。依據預設,架構中的相依性屬性支援單向繫結行為的資料繫結。如果沒有任何資料繫結的案例,您可以停用資料繫結 (因為它們較具彈性和擴充性,所以預設 WPFAPI 中沒有很多這類屬性的範例)。您可以設定讓繫結擁有雙向預設值,以用於可在控制項元件片段間結合控制項行為的屬性 (IsSubmenuOpen 即為一個範例),或者雙向繫結是使用者常見或預期案例的情況 (Text 即為一個範例)。變更資料繫結相關中繼資料只會影響預設值;若以個別繫結為基準,則可隨時變更預設值。如需繫結模型和一般繫結的詳細資訊,請參閱資料繫結概觀。
報告支援日誌記錄的應用程式或服務是否應該記錄屬性日誌 (Journal)。在一般項目中,日誌記錄並非預設啟用的功能,而是針對特定使用者控制項選擇性啟用的功能。這個屬性主要是供日誌記錄服務讀取,包括日誌記錄的 WPF 實作,而且通常是在使用者控制項上設定,例如在巡覽步驟間應該保留之清單內的使用者選取項目。如需日誌的詳細資訊,請參閱巡覽概觀。
讀取 FrameworkPropertyMetadata
前面連結的各個屬性都是 FrameworkPropertyMetadata 加入至其即時基底類別 UIPropertyMetadata 的特定屬性。根據預設,每一個屬性都是 false。在屬性的中繼資料要求時,知道這些屬性的值非常重要,因此應該嘗試將傳回的中繼資料轉換成 FrameworkPropertyMetadata,然後再視需要檢視個別屬性的值。
指定中繼資料
當您為了將中繼資料套用到新的相依性屬性註冊作業,而建立新的中繼資料執行個體時,您可以選擇所要使用的中繼資料類別:基底 PropertyMetadata 或某個衍生類別 (Derived Class) (例如 FrameworkPropertyMetadata)。一般來說,您應該使用 FrameworkPropertyMetadata,尤其是如果您的屬性與屬性系統和 WPF 功能 (例如配置和資料繫結) 有任何互動。另一個情況較複雜的選擇是從 FrameworkPropertyMetadata 衍生,以自行建立成員中具有額外資訊的中繼資料報告類別。或者,您也可以使用 PropertyMetadata 或 UIPropertyMetadata 以傳達實作功能的支援等級。
對於現有的屬性 (AddOwner 或 OverrideMetadata 呼叫),您應該一律覆寫為原始註冊作業所使用的中繼資料型別。
如果您要建立 FrameworkPropertyMetadata 執行個體,有兩種方法可以填入 (Populate) 傳達架構屬性特性的特定屬性值:
使用容許 flags 參數的 FrameworkPropertyMetadata 建構函式簽章 (Signature)。這個參數應該填入 FrameworkPropertyMetadataOptions 列舉型別旗標的所有必要組合值。
使用其中一個沒有 flags 參數的簽章,然後針對需要的每個特性變更,將 FrameworkPropertyMetadata 上的每個報告布林 (Boolean) 值設定為 true。如果使用這種方法,您必須在建構具有此相依性屬性的任何項目之前設定這些屬性;布林值屬性為讀寫屬性,如此才能讓這項行為避免使用 flags 參數,而且仍然會填入中繼資料,但是中繼資料必須在使用屬性之前加以有效密封。因此,嘗試在要求中繼資料之後設定屬性是無效的作業。
架構屬性中繼資料合併行為
覆寫架構屬性中繼資料時,不同的中繼資料特性會被合併或取代。
PropertyChangedCallback 會合併。如果您加入新的 PropertyChangedCallback,該回呼 (Callback) 會儲存在中繼資料裡。如果沒有在覆寫中指定 PropertyChangedCallback,PropertyChangedCallback 的值會從中繼資料裡指定它的最接近祖系提升為參考。
PropertyChangedCallback 的實際屬性系統行為如下:階層架構中所有中繼資料擁有者的實作都會保留並加入到資料表,屬性系統的執行順序為最深層衍生類別的回呼會最先叫用 (Invoke)。繼承回呼只會執行一次,而中繼資料則會將發出回呼的類別視為其擁有者。
DefaultValue 會被取代。如果沒有在覆寫中指定 PropertyChangedCallback,DefaultValue 的值會取自在中繼資料裡指定它的最接近祖系。
CoerceValueCallback 實作會被取代。如果您加入新的 CoerceValueCallback,該回呼會儲存在中繼資料裡。如果沒有在覆寫中指定 CoerceValueCallback,CoerceValueCallback 的值會從中繼資料裡指定它的最接近祖系提升為參考。
屬性系統行為是只會叫用直接中繼資料裡的 CoerceValueCallback。階層架構中其他 CoerceValueCallback 實作的參考都不會保留。
FrameworkPropertyMetadataOptions 的旗標會合併成位元 (Bitwise) 或作業,相對於繼承中繼資料之 FrameworkPropertyMetadata 上的各種布林屬性值。IsAnimationProhibited 會取代成任何新的值,或是會保存繼承中繼資料內的值。
此行為是由 Merge 實作,可在衍生的中繼資料類別上覆寫。