定義自訂類型以搭配 .NET XAML 服務使用

當您定義屬於商務物件的自訂類型,或是不相依于特定架構的類型時,您可以遵循某些 XAML 最佳做法。 如果您遵循這些作法,.NET XAML 服務及其 XAML 讀取器和 XAML 寫入器可以探索您類型的 XAML 特性,並使用 XAML 類型系統在 XAML 節點資料流程中提供適當的標記法。 本主題描述類型定義、成員定義和 CLR 的最佳做法,這些類型或成員的關聯性。

XAML 的建構函式模式和類型定義

若要在 XAML 中具現化為物件專案,自訂類別必須符合下列需求:

  • 自訂類別必須是公用的,而且必須公開無參數的公用建構函式。 (如需結構相關附註,請參閱下節)。

  • 自訂類別不得為巢狀類別。 全名路徑中的額外「點」會使類別命名空間除法模棱兩可,並干擾其他 XAML 功能,例如附加屬性。 如果物件可以具現化為物件專案,則建立的物件可以填滿任何將物件視為其基礎類型之屬性的屬性專案形式。

如果您啟用值轉換器,您仍然可以為不符合這些準則的類型提供物件值。 如需詳細資訊,請參閱 XAML 的類型轉換器和標記延伸。

結構

結構一律能夠透過 CLR 定義在 XAML 中建構。 這是因為 CLR 編譯器會隱含地建立結構的無參數建構函式。 這個建構函式會將所有屬性值初始化為預設值。

在某些情況下,不需要結構的預設建構行為。 這可能是因為 結構的目的是要以聯集的形式填滿值和函式。 作為等位,自主值可能會有互斥的解譯,因此,其屬性都無法設定。 WPF 詞彙中這類結構的範例是 GridLength 。 這類結構應該實作型別轉換子,以便以屬性形式表示值,方法是使用建立結構值的不同解譯或模式的字串慣例。 結構也應該透過非無參數建構函式公開程式碼建構的類似行為。

介面

介面可以做為成員的基礎類型。 XAML 類型系統會檢查可指派的清單,並預期提供做為值的物件可以指派給 介面。 只要相關的可指派類型支援 XAML 建構需求,介面必須如何呈現為 XAML 類型的概念。

Factory 方法

Factory 方法是 XAML 2009 功能。 他們會修改物件必須具有無參數建構函式的 XAML 準則。 本文未記載處理站方法。 請參閱 x:FactoryMethod 指示詞

列舉

列舉具有 XAML 原生類型轉換行為。 XAML 中指定的列舉常數名稱會根據基礎列舉類型解析,並將列舉值傳回 XAML 物件寫入器。

XAML 支援套 FlagsAttribute 用列舉的旗標樣式用法。 如需詳細資訊,請參閱 XAML 語法詳細 資料。 ( XAML 語法詳細 資料是針對 WPF 物件所撰寫,但該主題中的大部分資訊都與特定實作架構無關的 XAML 相關。

成員定義

類型可以定義 XAML 使用方式的成員。 類型可以定義可使用 XAML 的成員,即使該特定類型不可使用 XAML 也一樣。 這是可能的,因為 CLR 繼承。 只要繼承成員的某些類型支援 XAML 使用方式做為類型,而且該成員支援其基礎類型的 XAML 使用方式,或具有可用的原生 XAML 語法,該成員即為 XAML 使用。

屬性

如果您使用一般 CLR 和存取子模式和語言適當的關鍵字,將屬性定義為公用 CLR get 屬性,則 XAML 類型系統可以將屬性報告為成員,並提供屬性的適當資訊 XamlMember ,例如 IsReadPublicIsWritePublicset

特定屬性可以套用 TypeConverterAttribute 來啟用文字語法。 如需詳細資訊,請參閱 XAML 的類型轉換器和標記延伸。

如果沒有文字語法或原生 XAML 轉換,而且沒有進一步的間接轉換,例如標記延伸使用方式,屬性的類型( TargetType 在 XAML 類型系統中)必須能夠將目標型別視為 CLR 類型,將實例傳回 XAML 物件寫入器。

如果使用 XAML 2009, 如果不符合先前的考慮,可以使用 x:Reference Markup Extension 來提供值;不過,這比類型定義問題更多的使用問題。

事件

如果您將事件定義為公用 CLR 事件,XAML 型別系統可以將附隨報告為 成員,並 IsEvent 作為 true 。 連接事件處理常式不在 .NET XAML 服務功能的範圍內;線路會留給特定的架構和實作。

方法

方法的內嵌程式碼不是預設的 XAML 功能。 在大部分情況下,您不會直接從 XAML 參考方法成員,而且 XAML 中方法的角色只會提供特定 XAML 模式的支援。 x:FactoryMethod 指示詞 是例外狀況。

欄位​​

CLR 設計指導方針禁止非靜態欄位。 針對靜態欄位,您只能透過 x:Static Markup Extension 存取靜態域值;在此情況下,您不會在 CLR 定義中執行任何特殊動作來公開 x:Static 使用量的欄位

可附加的成員

可附加成員會透過定義型別上的存取子方法模式向 XAML 公開。 定義型別本身不需要做為物件可以使用 XAML。 事實上,常見的模式是宣告服務類別,其角色是擁有可附加成員並實作相關行為,但不會提供其他函式,例如 UI 標記法。 在下列各節中,預留位置 PropertyName 代表可附加成員的名稱。 該名稱在 XamlName 文法 必須有效。

請謹慎注意這些模式與類型的其他方法之間的名稱衝突。 如果成員存在符合其中一個模式的成員,即使不是您的意圖,也可以由 XAML 處理器將其解譯為可附加成員使用路徑。

GetPropertyName 存取子

存取子的 GetPropertyName 簽章必須是:

public static object GetPropertyName(object target)

  • target 物件可以指定為實作中的更特定類型。 您可以使用此選項來限定可附加成員的使用範圍;在預定範圍以外的用法會擲回不正確轉換例外狀況,然後由 XAML 剖析錯誤呈現。 參數名稱 target 不是必要專案,而是依慣例在大部分實作中命名 target

  • 傳回值可以指定為實作中的更特定類型。

若要支援 TypeConverter 可附加成員屬性使用方式的啟用文字語法,請套用 TypeConverterAttributeGetPropertyName 存取子。 套用至 get 而非 set 看似不直覺;不過,此慣例可支援可序列化唯讀附加成員的概念,這在設計工具案例中很有用。

SetPropertyName 存取子

存取子的 SetPropertyName 簽章必須是:

public static void SetPropertyName(object target, object value)

  • target您可以在實作中將 物件指定為更特定的類型,其邏輯和結果與上一節所述相同。

  • value 物件可以指定為實作中的更特定類型。

請記住,這個方法的值是來自 XAML 使用方式的輸入,通常是屬性形式。 從屬性表單中,文字語法必須支援值轉換器,而且您在 s 存取子上 GetPropertyName 屬性。

可附加的成員存放區

存取子方法通常不足以提供將可附加成員值放入物件圖形的方法,或擷取物件圖形中的值,並正確地序列化它們。 若要提供這項功能, target 先前存取子簽章中的物件必須能夠儲存值。 儲存機制應與可附加成員原則一致,該成員可附加至成員不在成員清單中的目標。 .NET XAML 服務透過 API IAttachedPropertyStoreAttachablePropertyServices 提供可附加成員存放區的實作技術。 IAttachedPropertyStore 由 XAML 寫入器用來探索存放區實作,而且應該在存取 target 子的 型別上實作。 靜態 AttachablePropertyServices API 會在存取子主體內使用,並依其 AttachableMemberIdentifier 參考可附加成員。

正確地將類型、成員和元件歸結為重要,以便向 .NET XAML 服務報告 XAML 類型系統資訊。 如果適用下列任一情況,則報告 XAML 類型系統資訊是相關的:

  • 您打算將類型與直接以 .NET XAML 服務 XAML 讀取器和 XAML 寫入器為基礎的 XAML 系統搭配使用。
  • 您可以定義或使用以這些 XAML 讀取器和 XAML 寫入器為基礎的 XAML 利用架構。

如需與自訂類型 XAML 支援相關的每個 XAML 相關屬性清單,請參閱 自訂類型和程式庫 的 XAML 相關 CLR 屬性。

使用方式

使用自訂類型時,標記作者必須對應包含自訂類型的元件和 CLR 命名空間的前置詞。 本主題中未記載此程式。

存取層級

XAML 提供載入和具現化具有 internal 存取層級的類型的方法。 提供這項功能,讓使用者程式碼可以定義自己的類型,然後從屬於相同使用者程式碼範圍的標記具現化這些類別。

WPF 的範例是每當使用者程式碼定義 UserControl 用來重構 UI 行為的 方法,但不是任何可能透過宣告 public 具有存取層級之支援類別所隱含的可能擴充機制的一部分時。 UserControl如果備份程式碼編譯成與 XAML 型別參考的相同元件,則可以使用存取權來宣告 internal 這類 。

對於在完全信任下載入 XAML 並使用 XamlObjectWriter 的應用程式,一律會啟用載入具有存取層級的 internal 類別。

對於在部分信任下載入 XAML 的應用程式,您可以使用 API 來控制存取層級特性 XamlAccessLevel 。 此外,延遲機制(例如 WPF 範本系統)必須能夠傳播任何存取層級許可權,並保留它們以供最終執行時間評估使用;這會透過傳遞 XamlAccessLevel 資訊在內部處理。

WPF 實作

WPF XAML 會使用部分信任存取模型,其中如果 BAML 在部分信任下載入,則存取限制為 AssemblyAccessTo BAML 來源的元件。 對於延遲,WPF 會使用 IXamlObjectWriterFactory.GetParentSettings 做為傳遞存取層級資訊的機制。

在 WPF XAML 術語中, 內部類型 是由同時包含參考 XAML 的相同元件所定義的類型。 這類類型可以透過刻意省略對應元件= 部分的 XAML 命名空間進行對應,例如 xmlns:local="clr-namespace:WPFApplication1" 。 如果 BAML 參考內部類型,且該類型具有 internal 存取層級,這會產生 GeneratedInternalTypeHelper 元件的類別。 如果您想要避免 GeneratedInternalTypeHelper ,您必須使用 public 存取層級,或必須將相關類別納入個別元件,並使該元件相依。

另請參閱