什麼是 XAML?
XAML 是一種聲明性標記語言。如同應用於 .NET Framework 編程模型一樣,XAML 簡化了為 .NET Framework 應用程式建立 UI 的過程。您可以在聲明性 XAML 標記中建立可見的 UI 元素,然後使用程式碼後置檔案(通過部分類別定義與標記相串連)將 UI 定義與運行時邏輯相分離。XAML 直接以程式集中定義的一組特定支援型別表示對象的執行個體化。
下面的樣本示範如何建立作為 UI 一部分的按鈕。此樣本的目的僅在於供您初步瞭解 XAML 是如何表示常用 UI 編程形式的(它不是一個完整的樣本)。
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
XAML 語法概述
XAML 對象元素
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
此樣本指定了兩個對象元素:<StackPanel>(含有內容,後面有一個結束標記)和 <Button .../>(自結束形式,包含幾個特性)。對象元素 StackPanel 和 Button 各映射到一個類名,這些類由 WPF 定義並且是 WPF 程式集的一部分。指定對象元素標記時會建立一條 XAML 處理指示來建立一個新執行個體。每個執行個體都是在分析和載入 XAML 時通過調用基礎類型的預設建構函式來建立的。
特性語法(屬性)
對象的屬性通常可表示為對象元素的特性。特性文法命名在特性文法中設定的屬性,後跟賦值運算子 (=)。特性的值始終以包含在引號中的字串的形式進行指定。
特性文法是最簡單有效屬性設定文法,並且對於曾使用過標記語言的開發人員而言在使用中是最直觀的文法。例如,以下標記將建立一個具有紅色文本和藍色背景的按鈕,還將建立指定為 Content 的顯示文本。
<Button Background="Blue" Foreground="Red" Content="This is a button"/>
屬性元素語法
對於對象元素的某些屬性,特性文法是不可能實現的,因為無法在特性文法的引號和字串限制內充分地表達提供屬性值所必需的對象或資訊。對於這些情況,可以使用另一個文法,即屬性元素文法。
屬性元素開始標記的文法為 <類型名稱.屬性名稱>。通常,該標記的內容是類型的一個對象元素,屬性會將該元素作為其值。指定內容之後,必須用一個結束標記結束屬性元素。結束標記的文法為 </類型名稱.屬性名稱>。
如果可以使用特性文法,那麼使用特性文法通常更為方便,且能夠實現更為精簡的標記,但這通常只是一個風格的問題,而不屬於技術限制。下面的樣本示範了在前面的特性文法樣本中設定的相同屬性,但這次對 Button 的所有屬性使用了屬性元素文法。
<Button>
<Button.Background>
<SolidColorBrush Color="Blue"/>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"/>
</Button.Foreground>
<Button.Content>
This is a button
</Button.Content>
</Button>
集合語法
XAML 語言套件含一些最佳化,可以產生可讀性更好的標記。其中的一項最佳化是:如果某個特定屬性採用集合類型,則您在標記中聲明為該屬性的值內的子項目的項將成為集合的一部分。在這種情況下,子物件元素的集合是設定為集合屬性的值。
下面的樣本示範為 GradientStops 屬性設定值的集合文法:
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
XAML 內容屬性
XAML 指定了一個語言功能,通過該功能,一個類可以指定它的一個且僅一個屬性為 XAML 內容屬性。該對象元素的子項目用於設定該內容屬性的值。換言之,僅對內容屬性而言,您可以在 XAML 標記中設定該屬性時省略屬性元素,並在標記中產生更直觀的父級/子級形式。
例如,Border 指定內容屬性 Child。系統處理下面兩個 Border 元素的方式相同。第一個元素利用了內容屬性文法而省略了 Border.Child 屬性元素。第二個元素顯式標明 Border.Child。
<Border>
<TextBox Width="300"/>
</Border>
<!--explicit equivalent-->
<Border>
<Border.Child>
<TextBox Width="300"/>
</Border.Child>
</Border>
作為 XAML 語言的規則,XAML 內容屬性的值必須完全在該對象元素的其他任何屬性元素之前或之後指定。例如,下面的標記無法進行編譯:
複製
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
有關 XAML 內容屬性的此項限制的更多資訊,請參見 XAML 文法詳述的“XAML 內容屬性”一節。
常值內容
有少量 XAML 元素可直接將文本作為其內容來處理。若要實現此功能,必須滿足以下條件之一:
- 類必須聲明一個內容屬性,並且該內容屬性必須是可賦值給字串的類型(該類型可以是 Object)。例如,任何 ContentControl 都將 Content 用作其內容屬性,並且其類型為 Object,這樣就支援實際的 ContentControl(例如,Button)上的如下用法:<Button>Hello</Button>。
- 類型必須聲明一個類型轉換器,該類型轉換器將常值內容用作其初始化文本。例如,<Brush>Blue</Brush>。這種情況實際上並不常見。
- 類型必須為已知的 XAML 語言基元。
內容屬性和集合語法組合
請看以下樣本:
<StackPanel>
<Button>First Button</Button>
<Button>Second Button</Button>
</StackPanel>
此例中,每個 Button 都是 StackPanel 的一個子項目。這是一個簡單直觀的標記,其中出於兩個不同的原因省略了兩個標記。
- 省略的 StackPanel.Children 屬性元素:StackPanel 從 Panel 派生。Panel 將 Panel.Children 定義為其 XAML 內容屬性。
- 省略的 UIElementCollection 對象元素:Panel.Children 屬性採用類型 UIElementCollection,該類型實現 IList。根據處理集合(例如 IList)的 XAML 規則,集合的元素標記可以省略。(在這種情況下,UIElementCollection 實際無法執行個體化,因為它沒有公開預設建構函式,這就是 UIElementCollection 對象元素以注釋形式出現的原因。)
<StackPanel>
<StackPanel.Children>
<!--<UIElementCollection>-->
<Button>First Button</Button>
<Button>Second Button</Button>
<!--</UIElementCollection>-->
</StackPanel.Children>
</StackPanel>
特性語法(事件)
特性文法還可用於事件成員,而不僅限於屬性成員。在這種情況下,特性的名稱為事件的名稱。在 XAML 事件的 WPF 實現中,特性的值是實現該事件的委託的處理常式的名稱。例如,以下標記將 Click 事件的一個處理常式指定給在標記中建立的 Button:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>
XAML 中的大小寫和空白
XAML 通常區分大小寫。出於解析支援型別的目的,WPF XAML 按照 CLR 區分大小寫相同規則區分大小寫。按名稱與程式集中的基礎類型進行比較或者與類型的成員進行比較時,對象元素、屬性元素和特性名稱均必須使用區分大小寫形式指定。XAML 語言關鍵字和基元也區分大小寫。值並不總是區分大小寫。值是否區分大小寫將取決於與採用該值的屬性關聯的類型轉換器行為,或取決於屬性值類型。例如,採用 Boolean 類型的屬性可以採用 true 或 True 作為等效值,但只是因為將字串轉換為 Boolean 的本機 WPF XAML 分析器類型轉換已經允許將這些值作為等效值。
WPF XAML 處理器和序列化程式將忽略或刪除所有無意義的空白,並正常化任何有意義的空白。這與 XAML 規範的預設空白行為建議一致。通常,只有當您在 XAML 內容屬性中指定字串時,此行為的重要性才會體現出來。簡言之,XAML 將空格、分行符號和定位字元轉化為空白格,如果它們出現在一個連續字串的任一端,則保留一個空格。有關 XAML 空白處理的完整說明不屬於本主題的討論範圍。
標記擴展
標記延伸是一個 XAML 語言概念。當用於提供特性文法的值時,大括弧({ 和 })表示標記延伸用法。此用法指示 XAML 處理系統不要像通常那樣將特性值視為一個文本字串或者可轉換為字串的值。
WPF 應用程式編程中最常用的標記延伸是 Binding(用於資料繫結運算式)以及資源引用 StaticResource 和 DynamicResource。通過使用標記延伸,即使屬性通常不支援特性文法,也可以使用特性文法為屬性提供值。標記延伸經常使用中間運算式類型實現一些功能,例如,延遲值或引用僅在運行時才存在的其他對象。
例如,下面的標記使用特性文法設定 Style 屬性的值。Style 屬性採用了 Style 類的一個執行個體,該執行個體預設情況下未能用特性文法字串執行個體化。但在本例中,特性引用了特定的標記延伸 StaticResource。當處理該標記延伸時,它返回對以前在資源字典中作為鍵控資源進行執行個體化的某個樣式的引用。
<Page.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="Background" Value="Blue"/>
</Style>
...
</Page.Resources>
<StackPanel>
<Border Style="{StaticResource PageBackground}">
...
</Border>
</StackPanel>
有關特定在 WPF 中實現的所有 XAML 標記延伸的參考列表,請參見 WPF XAML 擴充。有關由 System.Xaml 定義並且可更廣泛用於 .NET XAML 實現的標記延伸的參考列表,請參見 XAML 命名空間 (x:) 語言功能。有關標記延伸概念的更多資訊,請參見標記延伸和 WPF XAML。
類型轉換器
在一節中,曾提到特性值必須能夠使用字串進行設定。對字串如何轉換為其他物件類型或基元值的基本本機處理取決於 String 類型本身,以及對某些類型(如 DateTime 或 Uri)的本機處理。但是很多 WPF 類型或這些類型的成員擴充了基底字元串特性處理行為,因此可以指定更複雜的物件類型的執行個體作為字串和特性。
Thickness 結構是一個類型樣本,該類型擁有可使用 XAML 的類型轉換。Thickness 指示嵌套矩形中的度量並用作一些屬性(如 Margin)的值。通過對 Thickness 設定類型轉換器,所有使用 Thickness 的屬性都可以更容易地在 XAML 中指定,因為它們可指定為特性。下面的樣本使用類型轉換和特性文法來為 Margin 提供值:
<Button Margin="10,20,10,30" Content="Click me"/>
上面的特性文法樣本與下面更為詳細的文法樣本等效,但在下面的樣本中,Margin 改為通過包含 Thickness 對象元素的屬性元素文法進行設定。而且設定 Thickness 的四個關鍵屬性作為新執行個體的特性:
<Button Content="Click me">
<Button.Margin>
<Thickness Left="10" Top="20" Right="10" Bottom="30"/>
</Button.Margin>
</Button>
說明 |
還有少數對象只能通過類型轉換這種公開方式在不涉及到子類的情況下為該類型設定屬性,因為類型本身並沒有預設建構函式。一個樣本是 Cursor。 |
有關如何支援類型轉換及其在特性文法上的應用的更多資訊,請參見 TypeConverters 和 XAML。
XAML 根項目和 XAML 命名空間
一個 XAML 檔案只能有一個根項目,這樣才能同時成為格式正確的 XML 檔案和有效 XAML 檔案。對於典型的 WPF 方案,將使用在 WPF 應用程式模型中具有重要意義的根項目(例如,為頁使用 Window 或 Page,為外部字典使用 ResourceDictionary 或為應用程式定義使用 Application)。下面的樣本示範 WPF 頁的典型 XAML 檔案的根項目,此根項目為 Page。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
</Page>
根項目還包含特性 xmlns 和 xmlns:x。這些特性向 XAML 處理器指明哪些 XAML 命名空間包含標記將要作為元素引用的支援型別的類型定義。xmlns 特性明確指示預設的 XAML 命名空間。在預設的 XAML 命名空間中,可以不使用首碼指定標記中的對象元素。對於大多數 WPF 應用程式方案以及 SDK 的 WPF 部分中給出的幾乎所有樣本,預設的 XAML 命名空間均映射到為 WPF 命名空間 http://schemas.microsoft.com/winfx/2006/xaml/presentation。xmlns:x 特性指示另外一個 XAML 命名空間,該命名空間映射 XAML 語言命名空間 http://schemas.microsoft.com/winfx/2006/xaml。
使用 xmlns 定義用法範圍和名稱範圍映射的做法符合 XML 1.0 規範。XAML 名稱範圍與 XML 名稱範圍的不同僅在於:XAML 名稱範圍還包含有關進行類型解析和分析 XAML 時名稱範圍的元素如何受類型支援的資訊。
請注���,只有在每個 XAML 檔案的根項目上,xmlns 特性才是絕對必需的。xmlns 定義將適用於根項目的所有子代元素(此行為也符合 xmlns 的 XML 1.0 規範。)同時允許根以下的其他元素上具有 xmlns 特性,這些特性將適用於定義元素的任何子代元素。但是,頻繁定義或重新定義 XAML 命名空間可能會導致 XAML 標記樣式難以閱讀。
其 XAML 處理器的 WPF 實現包括可識別 WPF 核心程式集的基礎結構。已知 WPF 核心程式集包含支援 WPF 到預設 XAML 命名空間的映射的類型。這是通過屬於項目組建檔案以及 WPF 產生和項目系統一部分的配置來實現的。因此,為了引用來自 WPF 程式集的 XAML 元素,只需將預設 XAML 命名空間聲明為預設 xmlns。
x: 前綴
在上面的根項目樣本中,首碼 x: 用於映射 XAML 命名空間 http://schemas.microsoft.com/winfx/2006/xaml,該命名空間是支援 XAML 語言構造的專用 XAML 命名空間。在這整個 SDK 的項目模板、樣本以及文檔中,此 x: 首碼用於映射該 XAML 命名空間。XAML 語言的 XAML 命名空間包含多個將在 XAML 中頻繁用到的編程構造。下面列出了將用到的最常見的 x: 首碼編程構造:
- x:Key:為 ResourceDictionary(或其他架構中的類似字典概念)中的每個資源設定唯一的鍵。在典型的 WPF 應用程式標記中的所有 x: 用法中,x:Key 將可能佔到 90%。
- x:Class:向為 XAML 頁提供程式碼後置的類指定 CLR 命名空間和類名。必須具有這樣一個類才能支援每個 WPF 編程模型的程式碼後置,而正是因此,即使沒有資源,也幾乎總是能看到映射的 x:。
- x:Name:處理對象元素後,為運行時代碼中存在的執行個體指定運行時對象名稱。通常,您將為 x:Name 經常使用 WPF 定義的等效屬性。此類屬性特定映射到 CLR 後備屬性,因此更便於進行應用程式編程,在應用程式編程中,您經常使用運行時代碼從初始化的 XAML 中尋找命名元素。最常見的此類屬性是 FrameworkElement.Name。在特定類型中不支援等效的 WPF 架構級Name 屬性時,仍然可以使用 x:Name。某些動畫配置中會發生這種情況。
- x:Static:啟用一個返回靜態值的引用,該靜態值只能是一個 XAML 相容屬性。
- x:Type:根據類型名稱構造一個 Type 引用。它用於指定採用 Type(例如 Style.TargetType)的特性,但屬性經常具有原生字串到 Type 的轉換功能,因此使用 x:Type 標記延伸用法是可選的。
x: 首碼/XAML 命名空間中還有其他一些不太常見的編程構造。有關詳細資料,請參見 XAML 命名空間 (x:) 語言功能。
XAML 中的自定義前綴和自定義類型
對於您自己的自訂程式集或 PresentationCore、PresentationFramework 和 WindowsBase 的 WPF 核心以外的程式集,可以將該程式集指定為自訂 xmlns 映射的一部分。只要該類型能夠正確地實現以支援您所嘗試的 XAML 用法,就可以在 XAML 中引用該程式集中的類型。
下面是一個說明自訂首碼如何在 XAML 標記中工作的基本樣本。首碼 custom 在根項目標記中定義,並映射為隨應用程式一同打包並可用於該應用程式的一個特定程式集。此程式集包含 NumericUpDown 類型,實現該類型的目的是在支援常規 XAML 用法之外,還可以使用允許在 WPF XAML 內容模型的此特定點執行插入的類繼承。通過使用該首碼,此 NumericUpDown 控制項的一個執行個體聲明為對象元素,以便 XAML 分析器可找到包含該類型的 XAML 命名空間,從而找到包含該類型定義的後備程式集的位置。
複製
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:NumericUpDownCustomControl;assembly=CustomLibrary"
>
<StackPanel Name="LayoutRoot">
<custom:NumericUpDown Name="numericCtrl1" Width="100" Height="60"/>
...</StackPanel>
</Page>
有關 XAML 中自訂類型的更多資訊,請參見 XAML 及 WPF 的自訂類。
有關 XML 命名空間與程式集中後備代碼的命名空間如何相關的更多資訊,請參見 WPF XAML 的 XAML 命名空間和命名空間映射。
事件和 XAML 代碼隱藏
大多數 WPF 應用程式既包括 XAML 標記,也包括程式碼後置。在一個項目中,XAML 編寫為 .xaml 檔案,而 CLR 語言(如 Microsoft Visual Basic .NET 或 C#)用於編寫程式碼後置檔案。在 WPF 編程和應用程式模型中對 XAML 檔案進行標記編譯時間,XAML 檔案的 XAML 程式碼後置檔案的位置是通過如下方式來標識的:以 XAML 的根項目的 x:Class 特性形式指定一個命名空間和類。
在目前已介紹的樣本中,您已看到幾個按鈕,但還沒有一個按鈕具有任何關聯的邏輯行為。為對象元素添加行為的主要應用程式級機制是使用元素類的現有事件,並為在運行時引發該事件時調用的該事件編寫特定的處理常式。事件名稱以及要使用的處理常式的名稱在標記中指定,而實現處理常式的代碼在程式碼後置中定義。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim b As Button = e.Source
b.Foreground = Brushes.Red
End Sub
請注意,程式碼後置檔案使用 CLR 命名空間 ExampleNamespace 並將 ExamplePage 聲明為該命名空間內的一個部分類別。這相當於在標記根中提供的 ExampleNamespace.ExamplePage 的 x:Class 特性值。WPF 標記編譯器將通過從根項目類型派生一個類,為編譯的任何 XAML 檔案建立一個部分類別。當您提供也會定義同一部分類別的程式碼後置時,將在與編譯的應用程式相同的命名空間和類中組合產生的程式碼。
有關 WPF 中程式碼後置編程要求的更多資訊,請參見WPF 中的程式碼後置和 XAML 中的“程式碼後置、事件處理常式和部分類別要求”一節。
如果您不想建立一個單獨的程式碼後置檔案,還可以將代碼內聯到 XAML 檔案中。但是,內聯代碼是一種缺少多樣性的方法,有很多的限制。有關詳細資料,請參見WPF 中的程式碼後置和 XAML。
路由事件
路由事件是一個特殊的事件功能,該功能是 WPF 的基礎。路由事件使一個元素可以處理另一個元素引發的事件,前提是這些元素通過樹關係串連在一起。使用 XAML 特性指定事件處理時,可以對任何元素(包括未在類成員表中列出路由事件的元素)偵聽和處理該路由事件。這是通過以所屬類名限定事件名特性來實現的。例如,在當前所討論的 StackPanel / Button 樣本中,父 StackPanel 可以通過在 StackPanel 對象元素上指定特性 Button.Click,並使用處理常式名作為特性值,為子項目按鈕的 Click 事件註冊一個處理常式。有關路由事件如何工作的更多資訊,請參見路由事件概述。
XAML 命名元素
預設情況下,通過處理 XAML 對象元素在對象圖中建立的對象執行個體沒有唯一識別碼或對象引用。相反,如果在代碼中調用建構函式,則幾乎總是使用建構函式結果為構造的執行個體設定一個變數,以便以後在代碼中引用該執行個體。為了對通過標記定義建立的對象提供標準化訪問,XAML 定義了 x:Name 特性。您可以在任何對象元素上設定 x:Name 特性的值。在程式碼後置中,您選擇的標識符等效於引用所構造的執行個體的執行個體變數。在任何方面,命名元素都像它們是對象執行個體一樣工作(此名稱引用該執行個體),並且程式碼後置可以引用該命名元素來處理應用程式內的運行時互動。執行個體和變數之間的這種串連是由 WPF XAML 標記編譯器實現的,並且更具體涉及到功能和模式,例如本主題中將不詳細討論的 InitializeComponent。
WPF 架構級 XAML 元素繼承 Name 屬性,該屬性等效於 XAML 定義的 x:Name 特性。其他某些類也為 x:Name(通常也定義為 Name 屬性)提供屬性級等效項。一般而言,如果您在所選元素/類型的成員表中找不到 Name 屬性,則可以改用 x:Name。x:Name 值將通過特定子系統或通過諸如 FindName 等工具 + 生產力方法,為可在運行時使用的 XAML 元素提供標識符。
下面的樣本在 StackPanel 元素上設定 Name。然後,該 StackPanel 中的 Button 上的處理常式通過由 Name 設定的執行個體引用 buttonContainer 來引用 StackPanel。
<StackPanel Name="buttonContainer">
...
<Button Click="RemoveThis">Click to remove this button</Button>
</StackPanel>
Private Sub RemoveThis(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim fe As FrameworkElement = e.Source
If (buttonContainer.Children.Contains(fe)) Then
buttonContainer.Children.Remove(fe)
End If
End Sub
就像變數一樣,執行個體的 XAML 名稱受範圍概念的控制,因此可以在可預測的某個範圍內強制名稱唯一。定義頁面的主標記表示一個唯一的 XAML 名稱範圍,而該 XAML 名稱範圍的邊界就是該頁面的根項目。但是,其他標記源(如樣式或樣式中的模板)可以在運行時與頁面互動,這種標記源常常具有自己的 XAML 名稱範圍,這些名稱範圍不一定與頁面的 XAML 名稱範圍相關聯。有關 x:Name 和 XAML 名稱範圍的更多資訊,請參見 Name、x:Name 指令 或 WPF XAML 名稱範圍。
附加屬性和附加事件
XAML 指定了一個語言功能,該功能允許對任何元素指定某些屬性或事件,而不管要設定屬性或事件的元素的類型定義中是否存在該屬性或事件。該功能的屬性版本稱為附加屬性,事件版本稱為附加事件。從概念上講,可以將附加屬性和附加事件視為可以在任何 XAML 元素/對象執行個體上設定的全域成員。但是,元素/類或更大的基礎結構必須支援附加值的後備屬性儲存區。
通常通過特性文法來使用 XAML 中的附加屬性。在特性文法中,您可以採用“所有者類型.屬性名稱”的形式指定附加屬性。
表面上,這與屬性元素用法類似,但在這種情況下,您指定的“所有者類型”始終是一種與從中要設定附加屬性的對象元素不同的類型。“所有者類型”這種類型提供 XAML 處理器為擷取或設定附加屬性值所需要的訪問器方法。
使用附加屬性的最常見方案是使子項目能夠向其父元素報告屬性值。
下面的樣本示範了 DockPanel.Dock 附加屬性。DockPanel 類為 DockPanel.Dock 定義訪問器,因此擁有附加屬性。DockPanel 類還包括一個邏輯,該邏輯迭代其子項目並具體檢查每個元素是否具有 DockPanel.Dock 設定值。如果找到一個值,將在版面配置階段中使用該值定位子項目。使用 DockPanel.Dock 附加屬性和這種定位功能事實上是 DockPanel 類的激動人心的一面。
<DockPanel>
<Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
<Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>
在 WPF 中,大部分或所有附加屬性還作為依賴項屬性來實現。有關詳細資料,請參見附加屬性概述。
附加事件使用類似的“所有者類型.事件名”特性文法形式。就像非附加事件一樣,XAML 中的附加事件的特性值指定對元素處理事件時調用的處理常式方法的名稱。在 WPF XAML 中使用附加事件並不常見。有關更多資訊,請參見附加事件概述。