首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 學習筆記:XAML 深度解析 — 命名空間、屬性系統、標記延伸與動態載入

     編輯:關於.NET

XAML 定位:簡單、通用、聲明式的 DSL

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 命名空間:

  • System.Windows、System.Windows.Controls、System.Windows.Data、System.Windows.Media 等

XAML 專用命名空間 (System.Windows.Markup) 使用 x: 前綴:

<TextBox x:Name="txtUsername" Background="{x:Null}" />

引入自訂 CLR 命名空間

<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>

XAML 屬性值解析順序

  1. 以 { 開頭或衍生自 MarkupExtension → 標記延伸處理
  2. 有 TypeConverter 或 TypeConverterAttribute → 型別轉換器
  3. 嘗試基本型別轉換(含列舉名稱檢查)
<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 ...} - 資料繫結

定位參數 vs 命名參數

<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 作為內容屬性。

XamlReader / XamlWriter:執行期動態操作 XAML

編譯時 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。

序列化為 XAML

var xaml = XamlWriter.Save(new Window2());
MessageBox.Show(xaml);

輸出包含完整命名空間對應的 XAML 字串,動態換膚場景極具價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved