XAML 類型轉換器的概觀

物件寫入器的類型轉換器供應邏輯,可將 XAML 標記中的字串轉換為物件圖形中的特定物件。 在 .NET XAML 服務中,類型轉換器必須是衍生自 TypeConverter 的類別。 有些轉換器也支援 XAML 儲存路徑,而且可用來將序列化標記中的物件序列化成字串格式。 本主題描述如何以及何時叫用 XAML 中的類型轉換器,並提供 TypeConverter之方法覆寫的實作建議。

類型轉換概念

下列各節說明 XAML 如何使用字串的基本概念,以及 .NET XAML 服務中的物件寫入器如何使用類型轉換器來處理 XAML 來源中遇到的一些字串值。

XAML 和字串值

在 XAML 檔案中設定屬性值時,該值的初始類型是一般感應器中的字串,以及 XML 感應器中的字串屬性值。 甚至,其他基本類型 (例如 Double ) 一開始是 XAML 處理器的字串。

在大部分情況下,XAML 處理器需要兩項資訊才能處理屬性值。 第一項資訊是正在設定之屬性的實值類型。 任何定義屬性值並在 XAML 中處理的字串最後必須轉換或解析成該類型的值。 如果值是 XAML 剖析器可理解的基本類型 (例如數值),則會嘗試直接轉換字串。 如果屬性的值參考列舉,則會檢查提供的字串是否有該列舉中具名常數的名稱相符項。 如果值不是列舉型別的剖析器基本類型或常數名稱,則適用的型別必須能夠提供以轉換字串為基礎的值或參考。

注意

XAML 語言指示詞不會使用類型轉換器。

類型轉換器和標記延伸

XAML 處理器必須先處理標記延伸使用方式,才會檢查屬性類型和其他考量。 例如,如果設為屬性 (Attribute) 的屬性 (Property) 通常具有類型轉換,但在特定情況下是由標記延伸使用方式所設定,則會先處理標記延伸行為。 需要有標記延伸的一個常見情況是參考現有的物件。 在此案例中,無狀態類型轉換器只能產生新的執行個體,但這可能不是令人滿意的情況。 如需標記延伸的詳細資訊,請參閱 Markup Extensions for XAML Overview

原生類型轉換器

在 Windows Presentation Foundation (WPF) 和 .NET XAML 服務實作中,有某些 CLR 類型具有原生類型轉換處理。 不過,這些 CLR 類型通常不會被視為基本類型。 這類類型的範例是 DateTime。 其中一個原因是 .NET Framework 架構的運作方式:類型 DateTime 定義於 mscorlib (.NET 中的最基本程式庫)。 DateTime 不允許使用來自另一個引進相依性之元件的屬性來設定屬性( TypeConverterAttribute 來自系統)。 因此,不支援一般型別轉換器探索機制。 而是,XAML 剖析器都有一份需要原生處理的類型清單,而且這些類型的處理方式與 true 基本類型的處理方式類似。 如果是 DateTime則此處理包含 Parse呼叫。

實作類型轉換器

下列章節討論 TypeConverter 類別的 API。

TypeConverter

在 .NET XAML 服務下,所有用於 XAML 用途的類型轉換器都是衍生自基類 的類別 TypeConverterTypeConverter 類別要先存在於 .NET Framework 版本中,XAML 才會存在;其中一個原始 TypeConverter 案例是提供視覺化設計工具中屬性編輯器的字串轉換。

針對 XAML,會展開 TypeConverter 的角色。 基於 XAML, TypeConverter 是支援特定目標字串與來源字串轉換的基底類別。 來源字串會從 XAML 剖析字串屬性值。 目標字串可能會讓特定物件屬性的執行階段值處理回 XAML 中的屬性,以進行序列化。

TypeConverter 定義四個成員,而這些成員與基於 XAML 處理轉換目標字串和來源字串有關:

在這些成員中,最重要的方法是 ConvertFrom,可將輸入字串轉換成所需的物件類型。 ConvertFrom 方法可以實作以將更廣泛範圍的類型轉換為轉換器的預定目的地類型。 因此,它可以提供不僅 XAML 的用途,例如支援執行階段轉換。 不過,對於 XAML 使用,只有可處理 String 輸入的程式碼路徑才重要。

第二個最重要的方法是 ConvertTo 。 如果應用程式轉換成標記標記法(例如,如果將它儲存為 XAML 做為檔案), ConvertTo 則涉及 XAML 文字寫入器的較大案例,以產生標記標記法。 在此情況下,XAML 的重要程式碼路徑是呼叫端通過 destinationTypeString時。

CanConvertToCanConvertFrom 是服務查詢 TypeConverter 實作之功能時所使用的支援方法。 您必須實作這些方法來傳回轉換器對等轉換方法所支援類型特有案例的 true。 基於 XAML,這通常表示 String 類型。

XAML 的文化特性資訊和類型轉換器

每個 TypeConverter 實作都可以唯一解譯轉換的有效字串,也可以使用或忽略傳遞為參數的類型描述。 文化特性和 XAML 類型轉換的重要考量如下:雖然 XAML 支援使用可當地語系化字串做為屬性值,但是您無法使用這些可當地語系化字串做為具有特定文化特性需求的類型轉換器輸入。 這項限制是因為 XAML 屬性值的類型轉換器包含使用 en-US 文化特性的必要固定語言 XAML 處理行為。 如需這項限制之設計原因的詳細資訊,請參閱 XAML 語言規格 ( [MS-XAML] ) 或 WPF 全球化和當地語系化概觀

在文化特性可能是問題的範例中,某些文化特性會使用逗號 (而非句號) 做為字串形式中數字的小數點分隔符號。 這項使用與許多現有類型轉換器的行為衝突,後者是使用逗號做為分隔符號。 在周圍 XAML 中透過 xml:lang 傳遞文化特性並不能解決問題。

實作 ConvertFrom

若要可做為支援 XAML 的 TypeConverter 實作來重複使用,該轉換器的 ConvertFrom 方法必須接受字串做為 value 參數。 如果字串的格式有效,而且可以透過 TypeConverter 實作進行轉換,則傳回的物件必須支援轉型為屬性所預期的類型。 否則, ConvertFrom 實作必須傳回 null

每個 TypeConverter 實作都可以唯一解譯什麼可替代轉換的有效字串,也可以使用或忽略傳遞為參數的類型描述或文化特性內容。 不過,WPF XAML 處理可能不會在所有情況下都將值傳遞至類型描述內容,也可能不會根據 xml:lang來傳遞文化特性。

注意

請勿使用大括弧 ( {} ),特別是左大括弧 ({), 作為字串格式的元素。 這些字元保留做為標記延伸序列的進入及結束。

當您的類型轉換器必須能夠從 .NET XAML Services 物件寫入器存取 XAML 服務時,應該擲回例外狀況,但 GetService 針對內容進行的呼叫不會傳回該服務。

實作 ConvertTo

ConvertTo 可能用於序列化支援。 透過自訂類型和其類型轉換器之 ConvertTo 的序列化支援不是絕對需求。 不過,如果您正在實作控制項,或使用功能某部分的序列化或類別設計,則應該實作 ConvertTo

若要可做為支援 XAML 的 TypeConverter 實作來重複使用,該轉換器的 ConvertTo 方法必須接受所支援類型 (或值) 的執行個體做為 value 參數。 destinationType 參數的類型是 String時,傳回的物件必須可以轉型為 String。 傳回的字串必須代表 value 的序列化值。 理想上,您選擇的序列化格式應該可以產生相同的值,就像將該字串傳遞給相同轉換器的 ConvertFrom 實作,而不會明顯遺失資訊。

如果無法序列化值,或轉換器不支援序列化,則 ConvertTo 實作必須傳回 null 並可能會擲回例外狀況。 不過,如果您確實擲回例外狀況,則應該報告無法使用該轉換做為 CanConvertTo 實作的一部分;因此,支援先使用 CanConvertTo 檢查以避免例外狀況的最佳做法。

如果 destinationType 參數的類型不是 String,則可以選擇專屬轉換器處理。 一般而言,您會回復成基底實作處理,而在基底 ConvertTo 中會引發特定例外狀況。

當您的類型轉換器必須能夠從 .NET XAML Services 物件寫入器存取 XAML 服務時,應該擲回例外狀況,但 GetService 針對內容進行的呼叫不會傳回該服務。

實作 CanConvertFrom

您的 CanConvertFrom 實作應該傳回類型 truesourceTypeString ,否則會進行基底實作。 不會從 CanConvertFrom 擲回例外狀況。

實作 CanConvertTo

您的 CanConvertTo 實作應該傳回類型 truedestinationTypeString,否則會進行基底實作。 不會從 CanConvertTo 擲回例外狀況。

套用 TypeConverterAttribute

若要讓自訂類型轉換器做為 .NET XAML 服務自訂類別的代理型別轉換器,您必須將 套用 TypeConverterAttribute 至類別定義。 您透過屬性指定的 ConverterTypeName 必須是您自訂類型轉換器的類型名稱。 如果您套用這個屬性,則在 XAML 處理器處理屬性類型使用您自訂類別類型的值時,可以輸入字串,並傳回物件執行個體。

您也可以提供每個屬性的類型轉換器。 將 TypeConverterAttribute 套用至屬性定義 (主要定義,非其內的 get/set 實作),而不是將它套用至類別定義。 屬性的類型必須符合您自訂類型轉換器所處理的類型。 如果已套用這個屬性,則在 XAML 處理器處理該屬性的值時,可以處理輸入字串,並傳回物件執行個體。 如果您選擇從 Microsoft .NET Framework 使用屬性類型,或是無法控制類別定義且無法套用 TypeConverterAttribute 到其中的一些其他程式庫,則個別屬性類型轉換器技術很有用。

若要提供自訂附加成員的類型轉換行為,請將 TypeConverterAttribute 套用至附加成員之實作模式的 Get 存取子方法。

從標記延伸實作存取服務提供者內容

任何值轉換器的可用服務都會相同。 差異在於每個值轉換器如何接收服務內容。 存取服務和可用服務記載於 Type Converters and Markup Extensions for XAML主題中。

XAML 節點資料流中的類型轉換器

如果您是使用 XAML 節點資料流,則尚未執行類型轉換器的動作或最終結果。 在載入路徑中,最後需要進行類型轉換才能載入的屬性字串仍然維持為開始成員和結束成員內的文字值。 使用 XamlMember.TypeConverter 屬性可以判定這項作業最後需要的類型轉換器。 不過,從 XamlMember.TypeConverter 取得有效值是依賴具有 XAML 結構描述內容 (可透過基礎成員存取這類資訊) 或成員所使用物件值的類型。 叫用類型轉換行為時也需要 XAML 結構描述內容,因為這需要類型對應以及建立轉換器執行個體。

另請參閱