在 C# 與 XAML 的開發中(如 WPF、UWP、MAUI 等框架),x:Type是 XAML 中的標記擴展(Markup Extension),用於在 XAML 中表示.NET 類型的Type 對象,本質是將 XAML 中的類型名稱映射為 CLR 的System.Type實例。它是連接 XAML 聲明式語法與 C# 類型系統的關鍵工具,以下是其核心用法、場景及注意事項的詳解:
一、x:Type的基本語法
xml
{x:Type [命名空間:]類型名}
- 命名空間:若類型不在當前 XAML 的默認命名空間中,需指定命名空間前綴(需先在 XAML 根元素聲明命名空間映射);
- 類型名:目標 CLR 類型的名稱(如
Button、string、自定義類等)。
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)
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>
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 類型值
xml
<!-- 為Button類型定義樣式(TargetType需用x:Type指定) -->
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="FontSize" Value="14"/>
</Style>
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>
xml
<!-- ObjectDataProvider通過ObjectType指定要實例化的類型 -->
<ObjectDataProvider x:Key="ButtonProvider" ObjectType="{x:Type Button}">
<ObjectDataProvider.ConstructorParameters>
<sys:String>Click Me</sys:String>
</ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
3. 類型轉換器場景
xml
<!-- 自定義控件的類型映射 -->
<XmlnsDefinition AttributeKey="TypeName" AttributeValue="{x:Type local:MyCustomControl}"/>
4. 反射或動態類型操作
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:Type與typeof的關係
x:Type:XAML 標記擴展,在 XAML 編譯 / 解析時轉換為typeof(類型)的結果,生成System.Type實例;typeof(類型):C# 關鍵字,直接獲取類型的Type對象,與x:Type在功能上等價。
四、注意事項
<!-- 映射System命名空間(mscorlib程序集) -->
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<!-- 映射自定義程序集的命名空間 -->
xmlns:local="clr-namespace:MyApp;assembly=MyAppAssembly"
<!-- 簡化寫法(等價於TargetType="{x:Type Button}") -->
<Style TargetType="Button">
</Style>
<CollectionView.ItemsSource>
<col:List x:TypeArguments="x:String">
<x:String>Item1</x:String>
</col:List>
</CollectionView.ItemsSource>