XAML 概觀

更新:2007 年 11 月

本主題描述可延伸標記語言 (XAML) 語言的功能,並示範您可以如何使用 XAML 撰寫 Windows Presentation Foundation (WPF) 應用程式。本主題特別針對以 Windows Presentation Foundation (WPF) 實作的 XAML 進行描述。XAML 本身是比 Windows Presentation Foundation (WPF) 還要大的語言概念。

這個主題包含下列章節。

  • 具有流程控制支援的宣告式語言
  • XAML 物件項目
  • 設定屬性
  • 參考值和標記延伸
  • 啟用 Typeconverter 的屬性值
  • 集合型別和 XAML 集合屬性
  • XAML 內容屬性
  • XAML 中的大小寫和空白字元
  • 進一步了解 XAML 語法
  • XAML 根項目和 XML 命名空間
  • 事件和 XAML 程式碼後置
  • x:Name
  • 附加屬性和附加事件
  • 基底類別和 XAML
  • XAML 安全性
  • 從程式碼載入 XAML
  • 下一步
  • 相關主題

具有流程控制支援的宣告式語言

XAML 簡化了 .NET Framework 程式設計模型的 UI 建立。您可以在宣告式 XAML 標記中建立可見的 UI 項目,然後藉由使用程式碼後置 (Code-Behind) 的檔案 (已透過部分類別定義而聯結至該標記),區隔 UI 定義和執行階段邏輯。在 XAML 中使用標記混合程式碼的能力是很重要的,因為 XML 本身即是宣告式的,並不會真的提供流程控制模型的建議。以 XML 為基礎的宣告式語言,對於建立從原型 (Prototype) 到實際執行整個範圍中的介面而言是相當直覺化的,特別是針對具有 Web 設計和技術背景的人來說。不像其他大部分的標記語言,XAML 會直接表示執行個體化 (Instantiation) 的 Managed 物件。這項一般的設計準則對於 XAML 中所建立的物件,可以簡化程式碼和偵錯存取。

XAML 檔案是一種通常具有 .xaml 副檔名的 XML 檔案。

下列 XAML 範例顯示小型標記為何在建立按鈕做為 UI 的一部分時是必要的。建立的按鈕透過佈景主題樣式而具有預設視覺展示,並透過類別設計而具有預設行為。

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

XAML 物件項目

XAML 具有一組規則,用於將物件項目對應到類別或結構、將屬性 (Attribute) 對應到屬性 (Property) 或事件,以及將 XML 命名空間 (Namespace) 對應到 CLR 命名空間。XAML 項目會對應到參考組件中定義的 Microsoft .NET 型別,而屬性 (Attribute) 會對應到這些型別的成員。

前述範例指定兩個物件項目:<StackPanel> (具有結束標記) 以及 <Button/> (該按鈕也具有數個屬性 (Attribute),在接下來的小節會討論屬性)。字串 StackPanel 和 Button 會個別對應到的類別名稱,是由 WPF 所定義的,並會做為 WPF 組件的一部分。當您指定物件項目標記時,您建立的 XAML 處理指示,會在載入 XAML 頁面時建立具名類別的新執行個體。每個執行個體的建立,都是藉由呼叫基礎類別或結構的預設建構函式以及儲存結果而達成。為了要在 XAML 中做為物件項目使用,類別或結構必須公開 (Expose) 公用預設 (無參數) 建構函式。

設定屬性

XAML 中的屬性 (Property) 設定,是藉由使用各種可能的語法對物件項目設定屬性。特定屬性該使用哪種語法,會依據您所設定屬性的特性而異。

藉由設定屬性值,您即可對物件項目加入功能或特性。物件項目的基礎物件執行個體的初始狀態,是依據預設建構函式行為而定。通常應用程式不會完全使用任何特定物件的預設執行個體。

屬性語法

在 XAML 中,屬性 (Property) 通常可以用屬性 (Attribute) 表示。對於過去曾經使用標記語言的開發人員而言,屬性 (Attribute) 語法是最有效率的屬性 (Property) 設定語法,也是最為直覺化的使用語法。舉例來說,下列標記建立的按鈕會具有紅色文字和藍色背景,以及如 Content 所指定的顯示文字。

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

屬性項目語法

對於某些物件項目屬性 (Property) 而言,屬性 (Attribute) 語法並不適用,因為簡單字串並不足以表示用於提供屬性 (Property) 值所需的物件和資訊。對於這種情況,可以使用另一種稱為屬性 (Property) 項目語法的語法。屬性 (Property) 項目語法會以標記 (Tag) 內容來設定包含項目的參考屬性 (Property)。通常,內容會是屬性 (Property) 用來做為值用的型別的物件 (而其值所設定執行個體通常會以其他物件項目來指定)。屬性 (Property) 項目本身的語法是 <TypeName.Property>。指定內容後,就如同其他項目一樣,您必須以結尾標記 (Tag) 結束屬性 (Property) 項目 (使用語法 </TypeName.Property>)。對於同時支援屬性 (Attribute) 和屬性 (Property) 項目語法的屬性 (Property),這兩種語法通常具有相同的效果,雖然語法間有些微的差異,例如空白字元的處理。如果可以使用屬性 (Attribute) 語法,則使用屬性 (Attribute) 語法通常比較方便,並可以讓標記 (Markup) 更為精簡,不過這僅只是樣式上的問題,而非技術上的限制。下列範例顯示的屬性 (Property) 會設定成跟上述屬性 (Attribute) 語法範例相同,但這次會對 Button 的所有屬性 (Property) 使用屬性 (Property) 項目語法。

<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 的屬性 (Property) 項目語法,代表對基本的 XML 標記轉譯有很大的轉變。對於 XML,<TypeName.Property> 代表另一個項目,不見得代表它有這樣的關係:會成為 TypeName 父項目的子項目。而在 XAML 中,<TypeName.Property> 直接意味著 Property 是 TypeName 的屬性 (Property),要由屬性 (Property) 項目內容設定,絕不可能發生剛好是名稱內具有點號的類似名稱而卻不相關的項目。

屬性和類別繼承

屬性 (Property) 如果是出現為 WPF 項目的 XAML 屬性 (Attribute),則通常是繼承自基底類別 (Base Class)。舉例來說,在上述範例中,如果您曾經查看類別定義、反映 (Reflection) 結果或說明文件,就會發現 Background 屬性 (Property) 不是 Button 類別上直接宣告的屬性 (Property)。而 Background 是繼承自基底 Control 類別。

WPF XAML 項目的類別繼承行為,是另一個對基本的 XML 標記轉譯的重大轉變。在使用一般用於 XML 程式設計的結構描述類型 (例如 DTD 或 XSD 格式) 時,XAML 項目和其可允許的屬性 (Attribute) 組很難正確而完整地表示,類別繼承 (特別在中繼基底類別是抽象時) 是這個情形的一個原因。此外,XAML 中的 "X" 代表「可延伸」,而擴充性 (可延伸性) 即排除了任何完整表示「對 WPF 而言的 XAML」概念的可能性 (雖然維持獨立的 XML 命名空間定義可以協助解決這個問題,我們會在稍後的小節中討論這個概念)。

參考值和標記延伸

標記延伸是一種 XAML 概念。在屬性 (Attribute) 語法中,大括號 ({ 和 }) 代表標記延伸的使用。這項使用會指引 XAML 處理跳脫一般的屬性 (Attribute) 值處理方式 (即視為常值字串或直接字串轉換值)。

當屬性 (Property) 採用參考型別值時,這些屬性 (Property) 通常需要屬性 (Property) 項目語法 (一定會建立新的執行個體) 或是透過標記延伸的物件參考。標記延伸的使用可能可以傳回現有的執行個體,因而用途較廣或較不會導致物件負荷。

當使用標記延伸提供屬性 (Attribute) 值時,應該改用相關標記延伸的支援類別內的邏輯來提供屬性 (Attribute) 值。WPF 應用程式設計中最常使用的標記延伸是 Binding (用於資料繫結運算式) 以及資源參考 StaticResourceDynamicResource。藉由使用標記延伸,您可以使用屬性 (Attribute) 語法提供屬性 (Property) 的參考值,即使該屬性 (Property) 不支援直接物件執行個體化的屬性 (Attribute) 語法,或是啟用會將一般需求行為延後的特定行為 (XAML 屬性 (Property) 必須以該屬性 (Property) 型別值填入的需求)。

舉例來說,下列範例會使用屬性 (Attribute) 語法來設定 Style 屬性 (Property) 值。Style 屬性 (Property) 會採用 Style 類別的執行個體 (預設不能在屬性 (Attribute) 語法字串內指定的參考型別)。但在這個情況下,屬性 (Attribute) 會參考特定的標記延伸 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 擴充XAML 命名空間 (x:) 語言功能。如需標記延伸的詳細資訊,請參閱標記延伸和 XAML

啟用 Typeconverter 的屬性值

「屬性語法」一節陳述說屬性 (Attribute) 值必須能夠由字串設定。字串如何轉換成其他物件型別或基本值的基本原始處理方式,是依據 String 型別本身。但這些型別的許多 WPF 型別或成員,會擴充基本字串屬性 (Attribute) 處理行為,這樣更為複雜的物件型別執行個體才可以透過字串指定為屬性 (Attribute) 值。在程式碼層級上,這項處理是藉由指定用於處理字串屬性 (Attribute) 值的 CLR 型別轉換子 (Type Converter) 來達成。Thickness 結構型別 (Structure Type) 通常用於指示矩形區域的度量方法,例如 Margin,即是一個型別範例,會對採用該型別的所有屬性 (Property) 公開特定啟用的 typeconverter 屬性 (Attribute) 語法,以提供 XAML 標記的輕鬆用法。下列範例使用啟用 typeconverter 的屬性 (Attribute) 語法,以提供 Margin 值:

<Button Margin="10,20,10,30" Content="Click me"/>

前述屬性 (Attribute) 語法範例與下列更為詳細的語法範例是相等的,當中是改為透過包含 Thickness 物件項目的屬性 (Property) 項目語法來設定 Margin,並在新的執行個體上將四個主要的 Thickness 屬性 (Property) 設定為屬性 (Attribute)。

<Button Content="Click me">
  <Button.Margin>
    <Thickness Left="10" Top="20" Right="10" Bottom="30"/>
  </Button.Margin>
</Button>

是否要使用啟用 typeconverter 的語法或是更為詳細的對等語法,通常是屬於程式撰寫風格方面的選擇,但啟用 typeconverter 的語法可以達成更有效率的標記方式 (然而,對於少部分的物件而言,使用 typeconverter 設定該型別的屬性 (Property) 是唯一的方式,因為該型別物件本身沒有預設建構函式。Cursor 即為一個範例)。

如需啟用 typeconverter 屬性 (Attribute) 語法的支援方式的詳細資訊,請參閱 TypeConverter 和 XAML

集合型別和 XAML 集合屬性

XAML 指定有一個語言功能,可以從標記中刻意省略代表集合型別的物件項目。當 XAML 處理器處理採用集合型別的屬性 (Property) 時,會隱含建立適當的集合型別執行個體,即使標記中沒有該集合的物件項目。在集合型別的 SDK 參考頁面中,如果語法具有刻意省略的集合物件項目,則有時候會在 XAML 語法章節中標註為<隱含集合語法>。

隱含集合語法可以供實作 IListIDictionary 的型別或是供陣列使用。

雖然沒有特別指出,但您已經在 XAML 資源範例中看過隱含集合語法的範例:

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

除了根項目 (Element) 之外,頁面上的每個物件項目 (Element) 如果是巢狀結構中其他項目 (Element) 的子項目 (Element),那麼該項目 (Element) 實際上會屬於下列情況中的一或兩者:其父項目 (Element) 的隱含集合屬性的成員,或者是用於指定父項目 (Element) 的 XAML 內容屬性值的項目 (Element) (在接下來的小節中將討論 XAML 內容屬性)。換句話說,標記頁面中的父項目 (Element) 和子項目 (Element) 關係實際上是根項目上的單一物件,而根項目下的每個物件項目 (Element),不是提供父項目 (Element) 屬性值的單一執行個體,就是集合內的其中一個項目 (Item) (亦為父項目的集合型別屬性值)。在資源範例的情況中,Resources 屬性會採用 ResourceDictionary 的物件。下列範例與明確指定 ResourceDictionary 的物件項目 (Element) 是對等語法。

<Page.Resources>
  <ResourceDictionary>
      <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
      <Style TargetType="Border" x:Key="PageBackground">
        <Setter Property="Background" Value="Blue"/>
      </Style>


...


  </ResourceDictionary>
</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


    </Border>
  </StackPanel>
</Page>

Resources 集合是一個集合屬性範例,在許多常見的 WPF 架構層級項目 (Element) 中都存在。在 XAML 中設定這個屬性需要使用屬性項目 (Element) 語法。屬性項目 (Element) 內每個封入的物件項目 (Element) 會成為集合的項目 (Item) (IDictionary 實作)。雖然集合型別本身通常會有包含項目 (Item) 的屬性或索引子 (Indexer),但該屬性不能在標記中指定,它完全是隱含的。對於 ResourceDictionary,該屬性是 Item 索引子。

如需更完整的資源字典使用範例,請參閱 HOW TO:定義和參考資源

XAML 內容屬性

XAML 指定有一個語言功能,任何可以當做 XAML 物件項目使用的類別,都可以將其中一個屬性指定成為類別執行個體的 XAML 內容屬性。當 XAML 處理器處理的物件項目具有 XAML 內容屬性時,該物件項目的任何 XML 子項目的處理方式,就會如同它們在代表該內容屬性的隱含屬性項目標記 (Tag) 內一樣。在您的標記 (Markup) 內,可以省略 XAML 內容屬性的屬性項目語法。您在標記 (Markup) 中指定的任何子項目,都將成為 XAML 內容屬性的值。

雖然沒有特別指出,但您已經在本主題很前面的範例中看過 XAML 內容屬性的範例。

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

這裡的 ButtonStackPanel 的子項目。這段有效率而直覺化的標記 (Markup),基於兩個不同理由省略兩個標記 (Tag)。

  • Omitted StackPanel.Children 屬性項目StackPanel 衍生自 PanelPanel 會將 Panel.Children 定義為其 XAML 內容屬性。因而,Panel 的所有衍生類別都具有該 XAML 內容屬性,且 Panel.Children 的屬性項目可以省略。

  • Omitted UIElementCollection 物件項目Panel.Children 屬性會採用實作 IList 的型別 UIElementCollection。因此,依據集合的 UIElementCollection 定義規則,可以省略 XAML 物件項目標記 (Tag)。在這個情況下,UIElementCollection 實際上不能具現化為物件項目。您甚至無法選擇明確宣告該集合物件。這是因為 UIElementCollection 沒有公開預設建構函式。其他數種 WPF 集合型別也沒有公開物件項目使用的建構函式,因為 XAML 集合語法處理仍然允許它們在 XAML 中隱含運作。這就是 UIElementCollection 物件項目在範例中顯示為註解的原因,如果取消註解,就無法編譯範例。

<StackPanel>
  <StackPanel.Children>
    <!--<UIElementCollection>-->
    <Button>
      <Button.Content>
        Click Me
      </Button.Content>
    </Button>
    <!--</UIElementCollection>-->
  </StackPanel.Children>
</StackPanel>

內部文字和 XAML 內容屬性

StackPanel / Button 範例還有另一個變化形式。

<StackPanel>
  <Button>Click Me</Button>
</StackPanel>

請注意,Button 顯示文字的指定方式變更。Content 屬性 (Property) 過去是以屬性 (Attribute) 語法指定的,這次顯示字串則是 Button 物件項目內的內部文字。因為 ContentButton 基底類別 ContentControl 的 XAML 內容屬性 (Property),所以這個語法可以運作。項目內的字串評估是依據 Content 屬性 (Property) 的屬性 (Property) 型別,也就是 ObjectObject 並不會嘗試進行任何字串型別轉換,因此 Content 屬性 (Property) 值會成為常值字串值。或者,Button 內的內容可能是任何單一 ObjectButton 這類的控制項通常會定義類別的 XAML 內容屬性 (Property),這樣 XAML 內容屬性 (Property) 就可以用於 UI 和顯示文字、用於控制項複合,或者是同時用於這兩個情形。

將字串置放於項目內做為內容以產生類似於其他通用標記語言的標記的能力,對於非固定格式文件模型 (如需詳細資訊,請參閱 Windows Presentation Foundation 中的文件) 以及對於當地語系化 (請參閱全球化 Windows Presentation Foundation) 來說特別重要。

XAML 內容屬性值必須是連續

XAML 內容屬性 (Property) 值,必須在該物件項目上的任何其他屬性項目之前或之後完整指定。不論 XAML 內容屬性值是指定為字串或是指定為一個或多個物件皆如此。例如,下列標記無法編譯:

<Button>I am a 
  <Button.Background>Blue</Button.Background>
  blue button</Button>

這在本質上是不合法的,因為如果這個語法是藉由使用內容屬性的屬性項目語法而明確撰寫的,則設定了兩次該內容屬性:

<Button>
  <Button.Content>I am a </Button.Content>
  <Button.Background>Blue</Button.Background>
  <Button.Content> blue button</Button.Content>
</Button>

類似的不合法範例是當內容屬性是集合時,子項目卻穿插在屬性項目間:

<StackPanel>
  <Button>This example</Button>
  <StackPanel.Resources>
    <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
  </StackPanel.Resources>
  <Button>... is illegal XAML</Button>
</StackPanel>

內容模型

類別有可能在語法方面支援 XAML 項目的使用,但只有在該項目是置放於整體內容模型或項目樹狀結構的預期位置時,該項目才能在應用程式或頁面中正確運作。舉例來說,MenuItem 通常應該只能置放做為 Menu 這類 MenuBase 衍生類別的子項目。特定項目的內容模型的說明資訊,會在控制項的類別頁面以及可以用做 XAML 項目的其他 WPF 類別的備註部分。至於某些具有較複雜內容模型的控制項,內容模型的說明資訊會陳述在獨立的概念性主題中。請參閱內容模型

XAML 中的大小寫和空白字元

XAML 會區分大小寫。在依名稱與組件的基礎型別或與型別的成員進行比較時,物件項目、屬性 (Property) 項目和屬性 (Attribute) 名稱都必須使用適當的大小寫來指定。屬性 (Attribute) 值不一定會區分大小寫。值是否會區分大小寫的決定因素,在於採用該值的屬性 (Property) 或屬性 (Property) 值型別的相關型別轉換子行為。例如,接受 Boolean 型別的屬性 (Property) 可以將 true 或 True 視為對等值,但這僅是因為 Boolean 的預設字串型別轉換已經允許這兩者為對等用法。

XAML 處理器和序列化程式會忽略或捨棄所有不重要的空白字元,並將任何必要的空白字元標準化。這個行為通常只不過是您在 XAML 內容屬性 (Property) 內指定字串的必然結果。簡單地說,XAML 會將空白、換行字元和定位字元轉換成為空白,然後在連續字串兩端發現空白時保留一個空白。本主題並不涵蓋 XAML 空白字元處理的完整解說。如需詳細資訊,請參閱XAML 中的泛空白字元處理

進一步了解 XAML 語法

隱含集合語法和 XAML 內容屬性 (Property) 這兩個 XAML 語言功能,都可以省略某些推斷標記 (Tag)。這些功能的目標是要讓頁面上的項目父子關係,在撰寫或檢視標記 (Markup) 時更為明顯。

如需屬性 (Attribute) 語法和屬性 (Property) 項目語法的詳細資訊,以及整份 SDK 文件在描述 XAML 語法時所使用的其他詞彙,請參閱 XAML 語法術語。當您在建立自訂類別時,如果要考慮該如何啟用 XAML 的使用,XAML 語法術語主題也是很好的起點。

XAML 根項目和 XML 命名空間

XAML 檔案只能有一個根項目,這樣才能同時成為語式正確 (Well-Formed) 的 XML 檔案以及有效的 XAML 檔案。通常您應該選擇屬於應用程式模型之一部分的項目 (例如,頁面的 WindowPage、外部字典的 ResourceDictionary 或者是應用程式定義根項目的 Application)。下列範例顯示 WPF 頁面典型 XAML 檔案的根項目,而根項目為 Page

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"


...


</Page>

根項目也包含屬性 (Attribute) xmlns 和 xmlns:x。這些屬性向 XAML 處理器指出,哪些 XML 命名空間包含的項目定義,屬於標記將要參考的項目。xmlns 屬性會明確表示預設的 XML 命名空間。在預設的 XML 命名空間內,標記中的物件項目可以不使用前置字元指定。對於大部分的 WPF 應用程式案例而言,以及 SDK 的 WPF 章節中提供的幾乎所有範例,預設 XML 命名空間都會對應至 WPF 命名空間 https://schemas.microsoft.com/winfx/2006/xaml/presentation。xmlns:x 屬性則表示會對應至 XAML 語言命名空間 https://schemas.microsoft.com/winfx/2006/xaml 的其他 XML 命名空間。XAML 規格所定義的必要語言元件,在使用這個對應的檔案標記中參考時會以 x: 為前置字元。使用 xmlns 定義使用方式和對應的範圍,與 XML 1.0 規格是一致的。請注意,只有在標記中有提供 xmlns 屬性時,在每個頁面的根項目以及應用程式定義中才嚴格需要該屬性。xmlns 定義會套用到根項目的所有子項目上 (這個行為再度與 xmlns 的 XML 1.0 規格一致)。根項目下的其他項目也允許 xmlns 屬性,而且應該套用到該定義項目的任何子項目。然而,這個使用方式並不常用,因為定義過於頻繁或重新定義 XML 命名空間會造成 XAML 標記樣式難以閱讀。

我們都知道,在 WPF 組件包含的型別中,由於屬於專案建置檔案之一部分的組態,因此有支援預設 XML 命名空間的 WPF 對應的型別。組件也會對應到目標檔案。因此,對應 xmlns 是在要參考來自 WPF 組件的 XAML 項目時才必要。對於您自己的自訂組件或是 WPF 以外的組件,您可以指定組件做為 xmlns 對應的一部分。通常,您會選擇不同的前置字元,不過也可以選擇其他 XML 命名空間做為預設,然後再將 WPF 對應到前置字元。如需 XML 命名空間和組件中支援程式碼之命名空間的關聯方式的詳細資訊,請參閱 XAML 命名空間和命名空間對應

x: 前置字元

在前述的根項目範例中,前置字元 x: 是用於對應 XAML XML 命名空間 https://schemas.microsoft.com/winfx/2006/xaml。在本 SDK 的所有專案範本、範例和文件中,這個 x: 前置字元都會用於對應 XAML XML 命名空間。x: 前置字元/XAML XML 命名空間包含數種您會在 XAML 中頻繁使用的程式設計建構。下列清單是您將會最常使用的 x: 前置字元/XAML 命名空間程式設計建構:

  • x:Key:為 ResourceDictionary 中的每個資源設定唯一索引鍵。您在應用程式標記中看到的 x: 使用,將有 90% 是 x:Key。

  • x:Class:針對提供 XAML 頁面程式碼後置的類別,指定 CLR 命名空間和類別名稱。您必須有這類支援程式碼後置的類別,這也就是為什麼您幾乎都會看到 x: 對應,即使沒有資源也一樣。

  • x:Name:針對處理物件項目後存在於執行階段程式碼中的執行個體,指定執行階段物件名稱。對於沒有支援對等 WPF 架構層級 Name 屬性 (Property) 的命名項目情形,您會使用 x:Name。這會發生在某些動畫案例中。

  • x:Static:啟用會取得靜態值的值參考,這個值是在其他狀況下即無法相容於 XAML 的屬性。 

  • x:Type:依據型別名稱建構 Type 參考。這是用於指定會採用 Type 的屬性 (Attribute),例如 Style.TargetType,雖然在許多情況下,屬性 (Property) 具有原生的字串對 Type 轉換,讓 x:Type 的使用為選擇性的。

x: 前置字元/XAML 命名空間中還有其他的程式設計建構,但並不常用。如需詳細資訊,請參閱XAML 命名空間 (x:) 語言功能

事件和 XAML 程式碼後置

大部分的 WPF 應用程式同時由標記和程式碼後置所組成。專案內的 XAML 會撰寫成 .xaml 檔案,而 Microsoft Visual Basic .NET 或 C# 這類的 CLR 語言則用於撰寫程式碼後置的檔案。編譯 XAML 檔案時,每個 XAML 頁面的 XAML 程式碼後置檔案的位置識別,是藉由指定命名空間和類別做為 XAML 頁面根項目的 x:Class 屬性 (Attribute) 而達成的。

在目前的範例中,您已經看過幾種按鈕,但沒有一個按鈕具有任何相關聯的邏輯行為。用於加入物件項目行為的主要應用程式層級機制,是使用項目類別的現有事件,並為該事件撰寫在執行階段引發該事件時所叫用的特定處理常式。要使用的事件名稱和處理常式名稱是在標記中指定的,而實作處理常式的程式碼則是在程式碼後置中定義的。

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MyNamespace.MyPageCode">
  <Button Click="ClickHandler" >Click Me!</Button>
</Page>
namespace MyNamespace
{
  public partial class MyPageCode
  {
    void ClickHandler(object sender, RoutedEventArgs e)
    {
      Button b = e.Source as Button;
      b.Background = Brushes.Red;
    }
  }
}

請注意,程式碼後置檔案使用 CLR 命名空間 MyNamespace,並宣告 MyPageCode 做為該命名空間內的部分類別。這會平行處理標記根項目中所提供 MyNamespace.MyPageCode 的 x:Class 屬性 (Attribute) 值。編譯器會藉由衍生根項目型別的類別,為任何編譯的 XAML 頁面自動建立部分類別。當您提供的程式碼後置也會定義相同的部分類別時,產生的程式碼會結合在編譯過的應用程式的相同命名空間和類別內。

如需程式碼後置程式設計的需求的詳細資訊,請參閱程式碼後置和 XAML 的<程式碼後置、事件處理常式和部分類別需求>一節。

如果不想要建立獨立的程式碼後置檔案,您也可以在 XAML 檔案中內嵌 (Inline) 程式碼。然而,內嵌程式碼具有基本的限制,是一個用途較少的技術。如需詳細資訊,請參閱程式碼後置和 XAML

事件屬性語法

當您透過標記事件指定行為時,通常是使用屬性 (Attribute) 語法來附加處理常式。指定有事件屬性 (Attribute) 的物件項目,會成為接聽事件並呼叫處理常式的執行個體。而您要處理的特定事件的名稱則為屬性 (Attribute) 名稱。屬性 (Attribute) 值則是您要定義的處理常式的方法名稱。然後您必須在程式碼後置中提供處理常式的實作,同時處理常式要以該事件的委派為依據。在程式碼後置中的處理常式是以 Microsoft Visual Basic .NET 或 C# 這類的程式設計語言所撰寫的。

每個 WPF 事件會在引發事件時回報事件資料。事件處理常式可以存取這個事件資料。在前述範例中,處理常式是透過事件資料取得回報的事件來源,然後再於該來源上設定屬性 (Property)。

路由事件

對 WPF 來說有一個獨特而基本的特別事件功能,即為路由事件。路由事件可以讓項目處理由其他項目引發的事件,只要項目可以透過項目樹狀結構關係來連接。當使用 XAML 屬性 (Attribute) 指定事件處理時,路由事件可以由任何項目接聽和處理,包括類別成員表中沒有列出該特定事件的項目。這可以藉由使用主控類別名稱來限定事件名稱屬性而達成。例如,在持續進行的 StackPanel / Button 範例中的父項目 StackPanel,可以註冊子項目按鈕的 Click 事件的處理常式,方法是在 StackPanel 物件項目上指定屬性 Button.Click,並將處理常式名稱設為屬性值。如需詳細資訊,請參閱路由事件概觀

x:Name

根據預設,藉由處理物件項目而建立的物件執行個體,並不會有可以用於程式碼中的唯一識別項或與生俱來的物件參考。如果在程式碼中呼叫建構函式,幾乎都是使用建構函式結果來設定建構執行個體的變數,這樣您可於稍後在程式碼中參考執行個體。為了要對透過標記定義建立的物件提供標準化存取,XAML 定義了 x:Name 屬性。您可以對任何物件項目設定 x:Name 屬性 (Attribute) 值。在程式碼後置中,您選擇的識別項等同於代表建構執行個體的執行個體變數。就各方面來說,具名項目的運作方式就如同它們是物件執行個體一樣 (名稱只是參考該執行個體),而您的程式碼後置可以參考具名項目來處理應用程式內的執行階段互動。

WPF 架構層級 XAML 項目繼承的 Name 屬性 (Property),等同於 XAML 定義的 x:Name 屬性 (Attribute)。某些其他類別也會提供 x:Name 的屬性 (Property) 層級對等用法,通常也會定義為 Name 屬性 (Property)。一般來說,如果在成員表中找不到您選擇項目的 Name 屬性 (Property),則改用 x:Name。

下列範例會對 StackPanel 項目設定 Name。然後,該 StackPanelButton 的處理常式,會依據 Name 設定透過其執行個體參考 buttonContainer 來參考 StackPanel

<StackPanel Name="buttonContainer">


...


  <Button Click="RemoveThis">Click to remove this button</Button>
</StackPanel>
void RemoveThis(object sender, RoutedEventArgs e)
{
    FrameworkElement fe = e.Source as FrameworkElement;
    if (buttonContainer.Children.Contains(fe))
    {
        buttonContainer.Children.Remove(fe);
    }
}

就如同變數一樣,執行個體的名稱是由範圍的概念所控制,所以可以強制名稱在可預測的部分範圍內是唯一的。定義頁面的主要標記,表示一個唯一的名稱範圍,而名稱範圍的界限則是該頁面的根項目。然而,其他的標記來源可以於執行階段與頁面互動,例如樣式或樣式內的樣板,而這類標記來源通常具有自己的名稱範圍,其名稱範圍並不一定與頁面的名稱範圍有所連接。如需 x:Name 和名稱範圍的詳細資訊,請參閱 Namex:Name 屬性WPF 命名範圍

附加屬性和附加事件

XAML 指定有一個語言功能,可以讓某些屬性 (Property) 或事件在任何項目上指定,不論在所要設定的項目成員表中有沒有該屬性或項目。這個功能的屬性版本稱為附加屬性,事件版本則稱為附加事件。在概念上來說,您可以將附加屬性和附加事件,想像成是可以在任何項目 / 類別上設定的全域成員,不論類別的階層架構如何。

XAML 中的附加屬性 (Property) 通常是透過屬性 (Attribute) 語法使用。在屬性 (Attribute) 語法中您可以使用型式 OwnerType.PropertyName 指定附加屬性 (Property)。這有一點點像屬性 (Property) 項目的使用方式,不過這裡所指定的 OwnerType,一定不能是要設定附加屬性 (Property) 的物件項目的型別。OwnerType 這個型別所提供的存取子方法,是 a XAML 處理器在取得或設定附加屬性 (Property) 值時所必要的。最常見的附加屬性 (Property) 案例,是啟用子項目回報屬性 (Property) 值給父項目。

下列範例說明 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>

在 Windows Presentation Foundation (WPF) 中,所有的附加屬性也會以相依性屬性的方式實作。如需詳細資訊,請參閱附加屬性概觀

附加事件使用類似的屬性 (Attribute) 語法 OwnerType.EventName 型式。就像非附加事件一樣,XAML 中附加事件的屬性 (Attribute) 值會指定在項目上處理事件時叫用的處理常式方法名稱。 

有一個使用附加事件的案例,就是可以在任何項目 (例如滑鼠按鈕) 上處理的裝置輸入事件。這類附加事件的範例有 Mouse.MouseDown。然而,大部分的 WPF 架構層級項目可以在不使用附加事件的情況下直接使用這個事件。這是因為基底項目類別 UIElement 會建立 Mouse.MouseDown 附加事件的別名,並在 UIElement 成員表中公開該別名 (公開為 MouseDown)。因此,通常不需要在 XAML 頁面或 Windows Presentation Foundation (WPF) 應用程式設計中指定附加事件語法。例外的情況包括使用自訂項目,或不是衍生自 UIElement 但仍然具有視覺化呈現的物件項目 (這些都很少見)。在 WPF 中,所有的附加事件也會以路由事件的方式實作。ContentElement 也會公開輸入事件的別名,供非固定格式文件模型使用。如需詳細資訊,請參閱路由事件概觀輸入概觀

XAML 頁面根項目的結構分析

下表顯示一般的 XAML 頁面根項目細項,代表本主題指出的特定根項目屬性 (Attribute):

<Page

根項目的開頭物件項目

xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

預設 (WPF) 命名空間

xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

XAML 命名空間

x:Class="MyNamespace.MyPageCode"

將標記連接到定義在這個相同部分類別的任何程式碼後置的部分類別宣告

>

根項目的物件項目結尾,但因為頁面包含子項目而尚未結束

基底類別和 XAML

基礎 XAML 和其結構描述是類別集合,會對應到 CLR 物件以及 XAML 中使用的標記 (Markup) 項目。然而,並不是所有的類別都可以對應到項目。ButtonBase 這類的抽象類別 (Abstract Class) 和某些非抽象的基底類別,是用於 CLR 物件模型中的繼承,並且不支援對應的 XAML 標記 (Markup) 型態的標記 (Tag)。基底類別 (包含抽象類別) 對於 XAML 開發而言仍然很重要,因為每個具象的 XAML 項目會繼承階層架構中某些基底類別的成員。通常這些成員包含的屬性 (Property) 可以設定為項目的屬性 (Attribute),或是包含可以處理的事件。FrameworkElement 即是 WPF 於 WPF 架構層級的具象基底 UI 類別。設計 UI 時,您會使用各種圖案、面板、Decorator 或控制項類別,這些都是衍生自 FrameworkElement。有個相關的基底類別 FrameworkContentElement 會支援文件導向的項目,藉由使用特意與 FrameworkElement 中的 API 左右反轉的 API,這些項目在流程配置展示方面運作良好。結合項目層級的屬性 (Attribute) 和 CLR 物件模型,提供您可以在大多數具象 XAML 項目上設定的通用屬性 (Property),而不用在意確切的項目型別和其基礎類別。

XAML 安全性

XAML 是直接表示物件執行個體化和執行的標記語言。因此,XAML 中建立的項目在與系統資源互動方面 (例如網路存取、檔案系統 IO),跟對等的產生程式碼具有一樣的能力。

WPF 支援 .NET 安全性架構程式碼存取安全性 (CAS)。這表示在網際網路區域中執行的 WPF 內容的執行權限會降低。「鬆散的 XAML」(於載入時間由 XAML 檢視解譯的未編譯 XAML) 和 XAML 瀏覽器應用程式 (XBAP) 通常是在這個網際網路區域中執行,並具有相同的權限設定。然而,完全信任應用程式中載入的 XAML,與裝載應用程式具有相同的系統資源存取權限。如需詳細資訊,請參閱 Windows Presentation Foundation 部分信任安全性

從程式碼載入 XAML

XAML 可以用來定義整個 UI,但有時候也比較適合在 XAML 中定義僅一部分的 UI。這些功能可以用於啟用部分自訂、資訊的區域儲存區、使用 XAML 提供商務物件或是各種可能的案例。這些案例的關鍵在於 XamlReader 類別和其 Load 方法。輸入是 XAML 檔案,而輸出則是代表整個物件執行階段樹狀結構並由該標記建立的物件。接著,您可以將物件插入為應用程式中已經存在的其他物件的屬性 (Property)。只要在具有最後顯示能力且會通知執行引擎有新內容加入到應用程式的內容模型中,該屬性是適當的屬性,那麼藉由載入 XAML 就可以十分輕鬆地修改執行中應用程式的內容。請注意,這種能力通常只能在完全信任應用程式中使用,因為在應用程式執行時載入檔案會有很顯著的安全性影響。

下一步

本主題提供 XAML 語法概念和用語的基本簡介。如需這裡使用的詞彙的詳細資訊,請參閱 XAML 語法術語

如果還沒有進行 Windows Presentation Foundation 使用者入門教學課程,請嘗試完成。當您確實建立出教學課程所描述的標記應用程式時,藉由練習有助於強化本主題描述的許多概念。

WPF 使用的特別應用程式模型,是以 Application 類別為基礎。如需詳細資訊,請參閱應用程式管理概觀

關於如何從命令列和使用 Microsoft Visual Studio 建置內含 XAML 的應用程式,建置 WPF 應用程式 (WPF) 將提供您更為詳細的資訊。

相依性屬性概觀 提供您有關 Windows Presentation Foundation (WPF) 中多樣化屬性的詳細資訊,並介紹相依性屬性的概念。

最後,SDK 中含有稱為 XAMLPad 的 XAML 編輯工具。您可以使用這個工具來即時實驗 XAML。

請參閱

概念

XAMLPad

XAML 和自訂類別

基底項目概觀

WPF 中的樹狀結構

其他資源

XAML 命名空間 (x:) 語言功能

WPF 命名空間 XAML 擴充

內容模型