適用於型別轉換子和標記延伸的服務內容
在撰寫型別來支援使用型別轉換子和標記延伸時,通常必須先知道會在標記或周圍物件圖形結構中的何處使用型別轉換子和標記延伸。 要有這些資訊,才能正確地具現化所提供的物件,或是在物件圖形中建立對現有物件的物件參考。 使用 .NET Framework XAML 服務時,可能需要的內容資訊會以一系列服務介面的形式公開。 型別轉換子或標記延伸支援程式碼可以使用從 XamlObjectWriter 或相關型別傳來的可用服務提供者內容,來查詢服務。 XAML 結構描述內容可透過其中一個這類服務直接提供。 本主題說明如何透過值轉換子實作存取服務內容,並列出一般的可用服務及其角色。
這個主題包含下列章節。
- 取得服務
- 標記延伸適用的服務
- 型別轉換子適用的服務
- 值序列化程式適用的服務
- 使用 XAML 服務提供者內容
- .NET Framework XAML 服務內容提供的服務
- 相關主題
取得服務
身為值轉換子的實作者,您常會需要存取某種內容型別來套用值轉換子。 這個內容包含的資訊可能包括作用中的 XAML 結構描述內容,以及對 XAML 結構描述內容和 XAML 物件寫入器都會提供之型別對應系統的存取等等。 標記延伸或型別轉換子實作適用的可用服務,會透過每個虛擬方法之簽章中的內容參數來表示。 不論如何,您都會在內容中實作 IServiceProvider,並且可以呼叫 IServiceProvider.GetService 來要求服務。
標記延伸適用的服務
MarkupExtension 只有一種虛擬方法,即 ProvideValue。 輸入 serviceProvider 參數是在 XAML 處理器呼叫標記延伸時,用以向實作表示服務的途徑。 下列虛擬程式碼示範標記延伸實作如何在其 ProvideValue 中查詢服務:
public override object ProvideValue(IServiceProvider serviceProvider)
{
...
// Get the IXamlTypeResolver from the service provider
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
IXamlTypeResolver xamlTypeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
if (xamlTypeResolver == null)
{
throw new ArgumentException("IXamlTypeResolver"));
}
...
}
型別轉換子適用的服務
TypeConverter 有四個虛擬方法會使用服務內容而且支援使用 XAML。 每個方法都會傳遞輸入 context 參數。 這個參數屬於 ITypeDescriptorContext 型別,但是該介面會繼承 IServiceProvider,因此型別轉換子實作會有 GetService 方法可以使用。
下列虛擬程式碼示範用於 XAML 的型別轉換子實作如何在它其中一個覆寫 (在此案例中為 ConvertFrom) 中查詢服務:
public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext,
CultureInfo cultureInfo,
object source)
{
IRootObjectProvider rootProvider = typeDescriptorContext.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
if (rootProvider != null && source is String)
{
//return something, else ...
}
throw GetConvertFromException(source);
}
值序列化程式適用的服務
對於值序列化程式內容,您會使用 ValueSerializer 類別專屬的服務提供者型別 IValueSerializerContext。 該內容會傳遞給四個 ValueSerializer 虛擬方法的覆寫。 呼叫該內容中的 GetService,即可取得服務。
使用 XAML 服務提供者內容
讓 GetService 得以存取可用之標記延伸或型別轉換子 XAML 服務的服務提供者,會以內部類別的形式實作,而且僅會透過介面和在相關內容中用以傳遞服務提供者的管道來公開。 每當預設的載入路徑或儲存路徑 .NET Framework XAML 服務實作中的 XAML 處理作業,叫用需要服務內容的相關標記延伸或型別轉換子方法時,即會傳遞這個內部物件。 系統服務內容會根據當時的情況提供 MarkupExtensionContext 或 TextSyntaxContext,但這兩個類別的特性都會是內部形式。 您與這些類別進行的互動,僅限於透過 GetService 向類別要求服務。
.NET Framework XAML 服務內容提供的服務
.NET Framework XAML 服務可定義標記延伸、型別轉換子、值序列化程式甚或其他用法所適用的服務。 下列各節分別說明這些服務,並概略介紹實作可能會使用服務的方式。
IServiceProvider
參考文件:IServiceProvider
適用於:.NET Framework 中的服務型基礎結構的基本作業,可讓您呼叫 IServiceProvider.GetService。
ITypeDescriptorContext
從 IServiceProvider 衍生。 這個類別表示標準 TypeConverter 簽章中的內容;TypeConverter 是自 .NET Framework 1.0 版起即已存在的類別。它比 XAML 和用 TypeConverter 進行字串-值型別轉換的 XAML 情節都來得早。 在 .NET Framework XAML 服務內容中,TypeConverter 的方法會受到明確實作。 這個明確實作的行為會讓呼叫端知道,ITypeDescriptorContext API 與 XAML 型別系統無關,或與從 XAML 讀取或寫入物件無關。 Container、Instance 和 PropertyDescriptor 通常會從 .NET Framework XAML 服務內容傳回 null。
IValueSerializerContext
衍生自 ITypeDescriptorContext,而且也必須靠明確實作以抑制與 XAML 型別系統有關的錯誤假設。 支援 ValueSerializer 上的靜態查閱 Helper 方法。
IXamlTypeResolver
參考文件:IXamlTypeResolver
定義來源:System.Windows.Markup 命名空間、System.Xaml 組件
**適用於:**載入路徑情節,以及與 XAML 結構描述內容的互動。
服務 API:Resolve
可能會影響 XAML 寫入器在物件圖形中建構 CLR 物件時,需要進行的 XAML 對 CLR 型別對應。 Resolve 會處理與 XAML 型別名稱 (XamlType.Name) 對應的字串 (這個字串可能含限定前置詞),然後傳回 CLR Type。 解析型別的作業通常高度仰賴 XAML 結構描述內容。 只有 XAML 結構描述內容才可辨識已載入哪些組件,以及進行型別解析時可以或應該存取哪些組件。
IUriContext
參考文件:IUriContext
定義來源:System.Windows.Markup 命名空間、System.Xaml 組件
**適用於:**成員值 (URI 或 x:Uri 值) 的載入路徑和儲存路徑處理。
服務 API:BaseUri
這個服務會報告全域可用的 URI 根 (如果有的話)。 URI 根可用以將相對 URI 解析成絕對 URI (或反向作業)。 這個情節主要與特定架構所公開的應用程式服務,或是架構中常用之根項目類別的功能有關。 基底 URI 可建立為 XAML 讀取器設定,此設定接著會傳遞至 XAML 物件寫入器,並由此服務報告。
IAmbientProvider
參考文件:IAmbientProvider
定義來源:System.Xaml 命名空間、System.Xaml 組件
**適用於:**載入路徑處理和型別查閱的延後或最佳化。
服務 API:GetAllAmbientValues、其他 3 項。
XAML 中的環境概念是一種將型別的特定成員標記為環境成員的技術。 或者,您也可以將型別設為環境型別,使所有包含該型別之執行個體的屬性值都被視為環境屬性。 在物件圖形中的 XAML 節點資料流和子系內更深處的標記延伸或型別轉換子,可以在載入階段存取環境屬性或型別執行個體,或是在儲存階段使用環境結構的資訊。 這可能會影響其他服務 (如 IXamlTypeResolver 或 x:Type) 的型別解析作業所需的限定程度。 請參閱AmbientPropertyValue。
IXamlSchemaContextProvider
參考文件:IXamlSchemaContextProvider
定義來源:System.Xaml 命名空間、System.Xaml 組件
**適用於:**載入路徑,以及任何必須將 XAML 型別解析成備份型別的作業。
服務 API:SchemaContext
任何延後載入作業都必須用到 XAML 結構描述內容 (Context),因為相同的結構描述內容 (Context) 必須套用至延後的區域,才能整合延後的內容 (Content)。 如需 XAML 結構描述內容所扮演角色的詳細資訊,請參閱 XAML 服務。
IRootObjectProvider
參考文件:IRootObjectProvider
定義來源:System.Xaml 命名空間、System.Xaml 組件
**適用於:**載入路徑。
服務 API:RootObject
這項服務與由特定架構或由架構中常用根項目類別的功能所公開的應用程式服務有關。 連接程式碼後置和事件連接,就是一種需要取得根物件的情節。 例如,x:Class 的 WPF 實作會用來編譯標記,以及連接在 XAML 標記中的任何其他位置找到的任何事件處理常式屬性。 進行標記編譯時,標記和程式碼後置定義部分類別的連接點是在根項目。
IXamlNamespaceResolver
定義來源:System.Xaml 命名空間、System.Xaml 組件
**適用於:**載入路徑、儲存路徑。
服務 API:GetNamespace (適用於載入路徑)、GetNamespacePrefixes (適用於儲存路徑)。
IXamlNamespaceResolver 是一項服務,可根據 XAML 命名空間的前置詞,傳回 XAML 命名空間在起始 XAML 標記中的識別碼/URI。
IProvideValueTarget
參考文件:IProvideValueTarget
定義來源:System.Windows.Markup 命名空間、System.Xaml 組件
**適用於:**載入路徑和儲存路徑。
服務 API:TargetObject、TargetProperty。
IProvideValueTarget 可讓型別轉換子或標記延伸了解其要在載入階段發生作用的位置。 實作可以使用這個內容讓某個使用方式無效。 例如,WPF 在其某些標記延伸 (如 DynamicResourceExtension) 內具有邏輯。 此邏輯會檢查 TargetProperty,以確定該延伸只會用以設定相依性屬性 (或其他非相依性屬性的簡短清單)。
IXamlNameResolver
參考文件:IXamlNameResolver
定義來源:System.Xaml 命名空間、System.Xaml 組件
**適用於:**定義載入路徑物件圖形,解析由 x:Name、x:Reference 或架構專屬技術所識別的物件。
服務 API:Resolve;其他適用於進階情節 (例如處理向前參考) 的 API。
x:Reference 處理的 .NET Framework XAML 服務實作需倚賴這項服務。 特定架構或是支援該架構的工具,會使用這個服務來處理 x:Name 或是已用 RuntimeNamePropertyAttribute 屬性化(Attributed) 的對等屬性 (Property)。
IDestinationTypeProvider
定義來源:System.Xaml 命名空間、System.Xaml 組件
**適用於:**以載入路徑解析間接 CLR 型別資訊。
服務 API: GetDestinationType
如需詳細資訊,請參閱 IDestinationTypeProvider。