Microsoft 定義 XAML 為「簡單、通用、聲明式」的程式設計語言,而非單純 XML。所有定義直接對應 .NET 程式碼,由編譯器翻譯,設計階段即可預覽 UI 效果。
<Window x:Class="Learn.WPF.Window1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
<Grid />
</Window>
相當於:new Window1 { Title = "Window1" };
預設命名空間映射涵蓋 16 個 WPF 核心 CLR 命名空間:
XAML 專用命名空間 (System.Windows.Markup) 使用 x: 前綴:
<TextBox x:Name="txtUsername" Background="{x:Null}" />
<collections:Hashtable
xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:Int32 x:Key="key1">1</sys:Int32>
</collections:Hashtable>
<Label Name="label10" Foreground="Red">Label10</Label>
<Label Name="label11">
<Label.Content>Label11</Label.Content>
<Label.Foreground>Blue</Label.Foreground>
</Label>
{ 開頭或衍生自 MarkupExtension → 標記延伸處理TypeConverter 或 TypeConverterAttribute → 型別轉換器<Trigger Property="Visibility" Value="Collapsed,Hidden"> <!-- 列舉旗標組合 -->
WPF 內建大量轉換器,字串自動轉換為強型別:
<Label Foreground="Red" />
<!-- 等價於 -->
this.label.Foreground = System.Windows.Media.Brushes.Red;
<!-- 執行期實際行為 -->
var converter = TypeDescriptor.GetConverter(typeof(Brush));
this.label.Foreground = (Brush)converter.ConvertFromInvariantString("Red");
支援複雜屬性值,繼承自 MarkupExtension,以大括號包裹,可省略 Extension 後綴。
{x:Null} - 空值{x:Static Member} - 靜態成員值{StaticResource Key} - 靜態資源{DynamicResource Key} - 動態資源{Binding ...} - 資料繫結<Label Content="{x:Static SystemParameters.IconHeight}" />
<!-- 定位參數:傳給建構子 -->
<Label Content="{Binding ElementName=textBox1, Path=Text}" />
<!-- 命名參數:設定屬性 -->
<TextBox Name="textBox2" Width="128"
Text="{Binding RelativeSource={RelativeSource Self}, Path=Width}" />
將 TextBox.Text 繫結至自身 Width 屬性。
<Label Content="{}{Hello, World!}" />
<!-- 或直接放在元素內容 -->
<Label>{Hello, World!}</Label>
類似 HTML,元素可包含任意內容,UI 表達力極強:
<Button>
<Hyperlink>Click</Hyperlink>
</Button>
注意:ComboBox、ListBox、TabControl 使用 Items 作為內容屬性。
編譯時 XAML 壓縮為 BAML (Binary Application Markup Language) 嵌入資源。執行期解讀 BAML 產生元素物件。
var window = (Window)XamlReader.Parse(
"<Window xmlns=\"https://schemas.microsoft.com/winfx/2006/xaml/presentation\"></Window>");
window.ShowDialog();
using (var stream = new FileStream("test.xaml", FileMode.Open))
{
var window = (Window)XamlReader.Load(stream);
var button = (Button)window.FindName("btnOK");
button.Click += (s, ex) => MessageBox.Show("Hello!");
window.ShowDialog();
}
限制: 動態載入的 XAML 不可包含 x:Class 或 x:Code。
var xaml = XamlWriter.Save(new Window2());
MessageBox.Show(xaml);
輸出包含完整命名空間對應的 XAML 字串,動態換膚場景極具價值。