在 C# 與 XAML 的開發中(如 WPF、UWP、MAUI 等框架),x:Type是 XAML 中的標記擴展(Markup Extension),用於在 XAML 中表示.NET 類型的Type 對象,本質是將 XAML 中的類型名稱映射為 CLR 的System.Type實例。它是連接 XAML 聲明式語法與 C# 類型系統的關鍵工具,以下是其核心用法、場景及注意事項的詳解:

一、x:Type的基本語法

x:Type的語法格式為:

xml

{x:Type [命名空間:]類型名}
  • 命名空間:若類型不在當前 XAML 的默認命名空間中,需指定命名空間前綴(需先在 XAML 根元素聲明命名空間映射);
  • 類型名:目標 CLR 類型的名稱(如Buttonstring、自定義類等)。

示例

xml

<!-- 引用WPF內置的Button類型 -->
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ObjectDataProvider ObjectType="{x:Type Button}" />
</Window>

二、x:Type的核心應用場景

1. 指定類型參數(Type Arguments)

在 XAML 中聲明泛型類型時,需用x:Type指定泛型參數的類型,常見於List<T>Dictionary<TKey,TValue>等泛型集合或自定義泛型類。

示例 1:聲明泛型集合

xml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:col="clr-namespace:System.Collections.Generic;assembly=mscorlib">
    
    <!-- 聲明List<string>類型的資源 -->
    <col:List x:TypeArguments="{x:Type sys:string}" x:Key="StringList">
        <sys:string>Item1</sys:string>
        <sys:string>Item2</sys:string>
    </col:List>
    
    <!-- 聲明Dictionary<int, string>類型的資源 -->
    <col:Dictionary x:TypeArguments="{x:Type sys:Int32},{x:Type sys:string}" x:Key="IntStringDict">
        <sys:Int32 x:Key="1">One</sys:Int32>
        <sys:Int32 x:Key="2">Two</sys:Int32>
    </col:Dictionary>
</Window>

示例 2:自定義泛型類

csharp

運行

// C#自定義泛型類
public class MyGenericClass<T> {
    public T Value { get; set; }
}

xml

<!-- XAML中實例化MyGenericClass<string> -->
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyApp"
        xmlns:sys="clr-namespace:System;assembly=mscorlib">
    
    <local:MyGenericClass x:TypeArguments="{x:Type sys:string}" x:Key="MyGenericInstance">
        <local:MyGenericClass.Value>Hello</local:MyGenericClass.Value>
    </local:MyGenericClass>
</Window>

2. 設置依賴屬性的 Type 類型值

許多 WPF/UWP 控件的依賴屬性需要接收Type類型的值(如DataTemplateSelectorTargetTypeStyleTargetTypeObjectDataProviderObjectType等),此時需用x:Type指定目標類型。

示例 1:Style 的 TargetType

xml

<!-- 為Button類型定義樣式(TargetType需用x:Type指定) -->
<Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="LightBlue"/>
    <Setter Property="FontSize" Value="14"/>
</Style>

示例 2:DataTemplate 的 DataType

csharp

運行

// C#實體類
public class Person {
    public string Name { get; set; }
    public int Age { get; set; }
}

xml

<!-- DataTemplate關聯Person類型(DataType需用x:Type指定) -->
<DataTemplate DataType="{x:Type local:Person}">
    <StackPanel>
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding Age}"/>
    </StackPanel>
</DataTemplate>

示例 3:ObjectDataProvider 指定對象類型

xml

<!-- ObjectDataProvider通過ObjectType指定要實例化的類型 -->
<ObjectDataProvider x:Key="ButtonProvider" ObjectType="{x:Type Button}">
    <ObjectDataProvider.ConstructorParameters>
        <sys:String>Click Me</sys:String>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

3. 類型轉換器場景

部分屬性雖聲明為string類型,但實際需要解析為Type對象(如XmlnsDefinitionAttribute中的類型映射),此時x:Type可顯式提供類型信息,避免類型解析錯誤。

示例

xml

<!-- 自定義控件的類型映射 -->
<XmlnsDefinition AttributeKey="TypeName" AttributeValue="{x:Type local:MyCustomControl}"/>

4. 反射或動態類型操作

在 XAML 中需動態獲取類型信息(如通過Type參數調用靜態方法、實例化對象)時,x:Type是唯一的聲明式方式。

示例

csharp

運行

// C#工具類
public static class TypeHelper {
    public static object CreateInstance(Type type) {
        return Activator.CreateInstance(type);
    }
}

xml

<!-- XAML中調用靜態方法,傳入Type參數 -->
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyApp">
    
    <ObjectDataProvider ObjectType="{x:Type local:TypeHelper}"
                        MethodName="CreateInstance">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:Person"/> <!-- 傳入Person類型 -->
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window>

三、x:Typetypeof的關係

  • x:Type:XAML 標記擴展,在 XAML 編譯 / 解析時轉換為typeof(類型)的結果,生成System.Type實例;
  • typeof(類型):C# 關鍵字,直接獲取類型的Type對象,與x:Type在功能上等價。

等價示例:XAML 中的{x:Type Button} ≡ C# 中的typeof(Button)

四、注意事項

  1. 命名空間必須正確映射若類型不在默認命名空間(如http://schemas.microsoft.com/winfx/2006/xaml/presentation)中,需先在 XAML 根元素聲明命名空間前綴,例如:xml
<!-- 映射System命名空間(mscorlib程序集) -->
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<!-- 映射自定義程序集的命名空間 -->
xmlns:local="clr-namespace:MyApp;assembly=MyAppAssembly"
  1. 泛型參數的數量匹配使用x:TypeArguments時,參數數量需與泛型類的類型參數數量一致,多個參數用逗號分隔(如{x:Type sys:Int32},{x:Type sys:string})。
  2. 值類型與引用類型的區別x:Type可用於任何 CLR 類型(包括值類型如intbool,引用類型如string、自定義類),無需特殊處理。
  3. 簡化寫法的場景部分屬性(如Style.TargetType)在 XAML 中有簡化寫法,可省略x:Type直接寫類型名(編譯器會自動轉換):

    xml
<!-- 簡化寫法(等價於TargetType="{x:Type Button}") -->
<Style TargetType="Button">
</Style>

泛型參數、非默認命名空間的類型必須顯式使用x:Type

  1. MAUI 中的差異在 MAUI 中,x:Type的用法基本一致,但泛型聲明的語法略有調整(需用x:TypeArguments且支持更簡潔的寫法):

    xml
<CollectionView.ItemsSource>
    <col:List x:TypeArguments="x:String">
        <x:String>Item1</x:String>
    </col:List>
</CollectionView.ItemsSource>

五、總結

x:Type是 XAML 中獲取.NET 類型Type對象的核心工具,主要用於泛型類型聲明依賴屬性的 Type 參數設置反射場景的類型傳遞等。掌握其用法能讓 XAML 更靈活地與 C# 類型系統交互,尤其在自定義控件、數據模板、資源聲明等場景中不可或缺。需注意命名空間映射和泛型參數的正確性,避免類型解析錯誤。