共用方式為


XAML 語法詳細資料

本文件定義用來描述 XAML 語法元素的詞彙。 本文件其餘部分會經常使用這些詞彙,特別是 WPF 文件以及使用 XAML 或是 System.Xaml 層級上 XAML 語言支援的基本 XAML 概念的其他架構。 本主題將討論 WPF 中 XAML 主題中介紹的基本術語。

XAML 語言規格

這裡定義的 XAML 語法術語亦在 XAML 語言規格中定義或引用。 XAML 是以 XML 為基礎的語言,會遵循或擴充 XML 結構規則。 某些術語是借用或以描述 XML 語言或 XML 檔物件模型時常用的術語為基礎。

如需 XAML 語言規格的詳細資訊,請從 Microsoft 下載中心下載 [MS-XAML]

XAML 和 CLR

XAML 是標記語言。 通用語言執行平台 (CLR),如其名稱所示,可實現執行階段執行。 XAML 本身不是 CLR 執行平台直接取用的其中一種通用語言。 相反地,您可以認定 XAML 支援自己的型別系統。 WPF 所使用的特定 XAML 剖析系統以 CLR 和 CLR 型別系統為基礎。 XAML 型別會對應至 CLR 型別,以在剖析 WPF 的 XAML 時生成執行階段表示方式。 因此,本文件中語法討論的其餘部分會包含 CLR 型別系統的參考,即使 XAML 語言規格中對應的語法討論並未如此。 (根據 XAML 語言規格層級,XAML 型別可以對應至任何其他型別系統,並非 CLR 不可,但需要建立和使用不同的 XAML 剖析器。)

型別和類別繼承的成員

當屬性和事件顯示為 WPF 型別的 XAML 成員時,通常繼承自基本型別。 若以下方範例作說明:<Button Background="Blue" .../>. 如果您查看類別定義、反映結果或文件,則 Background 屬性 (property) 不是 Button 類別上立即宣告的屬性。 相反的,Background 是繼承自基本類別 Control

WPF XAML 元素的類別繼承行為與 XML 標記的結構描述強制解譯有顯著差異。 類別繼承有時相當複雜,特別是當中繼基本類別較抽象,或涉及介面時。 這是一組 XAML 元素及其允許的屬性很難正確表示,並完全使用通常用於 XML 程式設計的結構描述型別 (例如 DTD 或 XSD 格式) 的原因。 另一個原因是 XAML 語言本身的擴充性和型別對應功能排除了允許型別和成員之任何固定表示法的完整性。

物件元素語法

物件元素語法 是 XAML 標記語法,可藉由宣告 XML 元素來生成 CLR 類別或結構。 此語法類似於 HTML 等其他標記語言的元素語法。 物件元素語法的開頭是左角括弧 (<),後面緊接著要生成的類別或結構的型別名稱。 零個或多個空格可以接在型別名稱之後,而對象元素亦可宣告零個或多個屬性,其中一或多個空格會分隔每個屬性名稱 =“value” 組。 最後,需有至少下列任一情況為真:

  • 元素和標籤必須由正斜線 (/) 緊接右角括弧 (>) 包起。

  • 起始標籤必須以右角括弧結尾 (>)。 其他物件元素、屬性 (property) 元素或內部文字可以接在起始標籤之後。 此處可包含的內容通常受限於元素的物件模型。 物件元素對應的結束標籤亦應存在,與其他起始與結束標籤對形成對應與合適的巢狀結構。

.NET 運用的 XAML 有特定規則,會將物件元素對應至型別、屬性 (attribute) 對應至屬性 (property) 或事件,以及 XAML 命名空間對應至 CLR 命名空間加上組件。 就 WPF 和 .NET,XAML 物件元素會對應至參考組件中所定義的 .NET 型別,而屬性會對應至這些型別的成員。 當您在 XAML 中參考 CLR 型別時,您也可以存取該型別的繼承成員。

例如,下列範例是生成 Button 類別新執行個體,並指定 Name 屬性和對應值的物件元素語法:

<Button Name="CheckoutButton"/>

下列範例是物件元素語法,也包含 XAML 內容屬性 (property) 語法。 內含的內部文字將用來設定 TextBoxXAML 內容屬性 (property)Text

<TextBox>This is a Text Box</TextBox>

內容模型

一個類別在語法方面可能可做為 XAML 物件元素使用,但該元素只有在放置在整體內容模型或元素樹狀結構的預期位置時,才會在應用程式或頁面中正常運作。 例如,MenuItem 通常只能作為 MenuBase 衍生類別的子系放置,例如 Menu。 控制用類別頁面上的備註以及其他可作為 XAML 元素的 WPF 類別記載了特定元素的內容模型。

物件元素的屬性 (property)

XAML 中的屬性 (property) 可由多種語法設定。 根據您所設定之屬性的基礎型別系統特性,特定屬性可以使用哪一種語法會有所不同。

藉由設定屬性 (property) 值,您可以為物件新增功能或特性,因為它們存在於執行階段物件圖中。 自物件元素建立之物件的初始狀態是以無參數建構函式行為作為基礎。 一般而言,您的應用程式會使用任一物件的完全預設實例以外的狀態。

屬性 (Attribute) 語法 (屬性(Property))

屬性語法是藉由在現有物件元素上宣告屬性來設定屬性 (property) 值的 XAML 標記語法。 屬性名稱必須與對應相應物件元素之類別屬性 (property) 的 CLR 成員名稱對應。 屬性名稱後接指派運算符 (=)。 屬性值必須是以引號括住的字串。

注意

您可以使用交替引號,在屬性內放置常值引號。 例如,您可以使用單引號宣告包含雙引號字元的字串。 無論您使用單引號還是雙引號,都應該使用成對的符號來起始和結束屬性值字串。 任何特定 XAML 語法的字元限制也得透過逸出序列或其他技巧來迴避。 請見 XML 字元實體和 XAML

若要透過屬性語法設定屬性 (property),其必須為公用且可寫入的屬性。 型別系統中的 屬性值必須是實值型別,或者必須是在存取相關備份型別時,XAML 處理器可以具現化或參考的參考型別。

就 WPF XAML 事件,參考作為屬性名稱的事件必須為公用且有公用委派。

屬性或事件必須是由所包含之物件元素生成的類別或結構成員。

屬性值的處理

XAML 處理器會處理開頭和結尾引號中包含的字串值。 就屬性 (property) 而言,預設處理方式取決於其基礎 CLR 屬性類別。

屬性值依照本處理順序填入下方列出之值:

  1. 如果 XAML 處理器遇到大括弧或衍生自 MarkupExtension的物件元素,則會先評估參考的標記延伸,而不是將值當做字串處理,並以標記延伸傳回的物件作為填入值。 在許多情況下,標記延伸傳回的物件會是現有物件的參考,或是將評估延遲至執行階段的運算式,而且並非新生成的物件。

  2. 如果屬性 (property) 是以屬性 TypeConverter 宣告,或該屬性的數值類別是以屬性 TypeConverter 宣告,則屬性的字串值會提交給型別轉換器做為轉換輸入,而且轉換器會傳回新的物件實例。

  3. 如果沒有 TypeConverter,則轉換器會嘗試直接轉換成屬性型別。 這個最終層級是在 XAML 語言原始型別之間的剖析器原生值直接轉換,或檢查列舉中具名常數的名稱(剖析器接著會存取相符的值)。

列舉屬性值

XAML 中的列舉是由 XAML 剖析器以內建函式處理,而列舉的成員應該藉由指定列舉的其中一個具名常數的字串名稱來指定。

對於非標幟列舉值,原生行為是處理屬性值的字串,並將其剖析為其中一個列舉值。 與在程式碼中不同,您不會以 Enumeration.value 格式指定列舉。 相反地,您只會指定 0Value,而 Enumeration 是由您設定的屬性 (property) 型別推斷。 如果您以 Enumeration.value 指定屬性,它將無法正確剖析。

標幟列舉行為則根據 Enum.Parse 方法。 您可以藉由以逗號分隔每個值,為標幟列舉指定多個值。 不過,您無法合併非標幟的列舉值。 例如,您無法使用逗號語法來建立依據非標幟列舉的多個條件運行的 Trigger

<!--This will not compile, because Visibility is not a flagwise enumeration.-->  
...  
<Trigger Property="Visibility" Value="Collapsed,Hidden">  
  <Setter ... />  
</Trigger>  
...  

支援 XAML 中可設定之屬性的標幟列舉在 WPF 中很少見。 StyleSimulations 則是這少數的例外之一。 例如,您可以使用逗號分隔的標幟屬性語法來修改 Glyphs 類別的註解中提供的範例; StyleSimulations = "BoldSimulation" 可以變成 StyleSimulations = "BoldSimulation,ItalicSimulation"KeyBinding.Modifiers 是另一個屬性,其中可以指定多個列舉值。 不過,這個屬性恰好是特殊案例,因為 ModifierKeys 列舉有它自己的型別轉換器。 修飾符的型別轉換器會使用加號 (+) 做為分隔符,而不是逗號 (,)。 這項轉換支援更傳統的語法,以代表 Microsoft Windows 程式設計中的按鍵組合,例如 “Ctrl+Alt”。

屬性 (property) 和事件成員名稱參考

指定屬性時,您可以參考任何屬性 (property) 或事件,做為您為包含物件元素生成之 CLR 型別的成員。

或者,您可以參考與包含的物件元素無關之附加屬性或附加事件。 (後續章節將討論附加屬性。)

您也可以使用 typeName,以任何可透過預設命名空間存取的物件命名任何事件。事件部分限定名稱:此語法支援為路由事件附加處理常式,其中處理常式是為處理子元素的事件路由而存在,但父元素在其成員表中並沒有該事件。 此語法類似於附加事件語法,但這裡的事件不是真正的附加事件。 相反地,您是參考具有限定名稱的事件。 如需詳細資訊,請參閱路由事件概觀

在某些情況下,屬性 (property) 名稱有時會以屬性的值提供,而不是屬性名稱。 該屬性名稱也可以包含限定符,例如以 ownerType.dependencyPropertyName 形式指定的屬性。 以 XAML 撰寫樣式或範本時,這種情況很常見。 以屬性值提供之屬性名稱的處理規則不同,而且會受所設定之屬性的型別或特定 WPF 子系統的行為所控管。 如需詳細資訊,請參閱樣式和範本化

屬性名稱的另一個用法是當屬性值描述屬性—屬性關聯性時。 此功能用於資料系結和分鏡腳本目標,並透過 PropertyPath 類別及其型別轉換器使用。 如需查閱 lookup 語法較完整的描述,請參閱 PropertyPath XAML 語法

屬性元素語法

屬性 (Property) 元素語法 是與元素的基本 XML 語法規則有些差異的語法。 在 XML 中,屬性的值是事實字串,唯一可能的變化是使用字串編碼格式。 在 XAML 中,您可以將其他物件元素指派為屬性的值。 這項功能透過屬性元素語法實現。 屬性並非在項目標籤內被指定為屬性,而是使用 elementTypeName.propertyName 形式的起始元素標籤來指定,並在指定屬性的值後結束。

物件元素語法的開頭是左角括弧 (<),後面緊接著要內含屬性元素語法之類別或結構的型別名稱。 一個點 (.) 會緊接其後,接著是屬性的名稱,然後接上右角括弧 (>)。 如同屬性語法,該屬性 (property) 必須存在於指定型別的宣告公用成員內。 要指派給屬性的值包含在屬性元素內。 一般而言,此值會以一個或多個物件元素的形式給定,因為將物件指定為值便是屬性元素語法欲處理的情境。 最後,您必須加上指定相同的 elementTypeName.propertyName 組合之結束標籤。 並以適當的巢狀結構與其他元素標籤維持一致。

例如,以下是 ButtonContextMenu 屬性之屬性元素語法。

<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

如果指定的屬性型別是基本實值型別,例如 String,或是指定名稱的列舉型別,屬性元素內的值也可以指定為內部文字。 這兩種用法較不常見,因為上述兩種案例也可以使用更簡單的屬性 (attribute) 語法。 使用字串填滿屬性元素的其中一個案例,用於非 XAML 內容屬性的屬性但仍用於表示 UI 文字的屬性,特別是必須出現在該 UI 文字中的換行字元等空白字元。 屬性語法無法保留換行字元,但屬性元素語法可以,只要重要的空格符保留有在執行 (如需詳細資訊,請參閱 XAML 中的空白字元處理)。 另一個案例是令 x:Uid 指示詞可以套用至屬性元素,將當中的值標示為以 WPF 輸出 BAML 或其他方法本地化的值。

WPF 邏輯樹狀結構中不會表示屬性元素。 屬性元素只是設定屬性的特定語法,而且不是具有實例或物件支援的元素。 (如需邏輯樹狀結構概念的詳細資訊,請參閱 WPF 中的樹狀結構。)

對於同時支援屬性 (attribute) 和屬性 (property) 元素語法的屬性,這兩個語法通常會有相同的結果,不過空白字元處理等細微差別在兩者之間可能會稍有不同。

集合語法

XAML 規格需要 XAML 處理器實作,以識別實值型別為集合的屬性。 .NET 中一般 XAML 處理器實作是以受控碼和 CLR 為基礎,並透過下列其中一項來識別集合型別:

如果屬性的型別是集合,則推斷的集合型別不需要在標記中指定為物件元素。 相反地,欲納入集合中的元素會指定為屬性元素的一個或多個子元素。 在載入和加入集合期間,每個這類項目都會透過呼叫隱含集合的 Add 方法評估為物件。 例如, StyleTriggers 屬性會採用特製化集合型別 TriggerCollection,並實行 IList。 您不需要在標記中生成 TriggerCollection 物件元素。 相反地,您可以在預期 Trigger (或衍生類別) 是強型別和隱含 TriggerCollection 型別時將一個或多個 Trigger 項目指定為 Style.Triggers 屬性元素內的元素。

<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
  <Style.Triggers>
    <Trigger Property="Button.IsMouseOver" Value="true">
      <Setter Property = "Background" Value="Red"/>
    </Trigger>
    <Trigger Property="Button.IsPressed" Value="true">
      <Setter Property = "Foreground" Value="Green"/>
    </Trigger>
  </Style.Triggers>
</Style>

屬性可以同時是該型別和衍生型別的集合型別和 XAML 內容屬性,本文下一節將進行討論。

隱含集合元素會在邏輯樹狀結構表示中建立成員,即使它不會在標記中以元素形式出現也一樣。 父型別的建構函式通常會自身其中一個屬性之集合進行生成,而最初的空白集合會成為物件樹狀結構的一部分。

注意

集合偵測不支援泛型清單和字典介面 (IList<T>IDictionary<TKey,TValue>)。 不過,您可以使用 List<T> 類別做為基底類別,因為它會直接實行 IList,或以 Dictionary<TKey,TValue> 做為基類,因為它會直接實行 IDictionary

這個為集合刻意移除物件元素的語法偶爾會在集合型別的 .NET 參考頁面的 XAML 語法章節中被稱為隱含集合語法。

除了根元素之外,XAML 檔案中每個作為子元素與另一個元素呈巢狀結構的物件元素,其實都是下列兩種情況中的一種,或兩者皆符合:其父元素之隱含集合屬性的成員,或指定父元素之 XAML 內容屬性值的元素 (XAML 內容屬性會在後續章節討論)。 換句話說,標記頁面中父元素和子元素的關係實際是根上的單一物件,而根底下的每個物件元素都是提供父系屬性值的單一執行個體,或是集合中同時是父元素集合類型屬性值的項目。 這個單一根概念與 XML 通用,而且經常在載入 XAML 的 API 行為中加強,例如 Load

下列範例是其中物件元素經明確指定之集合 (GradientStopCollection) 的語法。

<LinearGradientBrush>  
  <LinearGradientBrush.GradientStops>  
    <GradientStopCollection>  
      <GradientStop Offset="0.0" Color="Red" />  
      <GradientStop Offset="1.0" Color="Blue" />  
    </GradientStopCollection>  
  </LinearGradientBrush.GradientStops>  
</LinearGradientBrush>  

請注意,集合未必每次都能明確宣告。 例如,嘗試在先前顯示的 Triggers 範例中明確宣告 TriggerCollection 就會失敗。 明確宣告集合需要集合類別支援無參數建構函式,而且 TriggerCollection 沒有無參數建構函式。

XAML 內容屬性

XAML 內容語法是只在類別宣告中指定 ContentPropertyAttribute 的類別中可用的語法。 ContentPropertyAttribute 會參考該型別元素的內容屬性名稱(包括衍生類別)。 由 XAML 處理器處理時,在物件元素的起始和結束標籤之間找到的任何子元素或內部文字,都會指派為該物件的 XAML 內容屬性值。 您可以指定內容屬性的明確屬性元素,但此用法通常不會在 .NET 參考的 XAML 語法章節中列出。 明確指定技巧偶爾會在需要清楚標記或需考慮標記樣式顯現其價值,但通常內容屬性的意圖是簡化標記,讓直覺應為父子關係的元素可以直接巢狀化。 若以嚴格的 XAML 語言定義,元素其他屬性的屬性元素標籤不會指派為「內容」:它們先前已在 XAML 剖析器處理順序中進行處理,且不會被視為「內容」。

XAML 內容屬性值必須是連續的

XAML 內容屬性的值必須完全指定在該物件元素上的任何其他屬性元素前後完整指派。 不論 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 處理器必須識別屬於集合型別的型別。 如果元素具有 XAML 內容屬性,且 XAML 內容屬性的型別是集合,則隱含集合型別不需要在標記中指定為物件元素,而且 XAML 內容屬性不需要指定為屬性元素。 因此,標記中的內容模型可以指派多個子元素做為內容。 以下是衍生類別 Panel 的內容語法。 所有 Panel 衍生類別都會建立 Children 的 XAML 內容屬性,這需要型別為 UIElementCollection 的值。

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
  <StackPanel>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
    <Button>Button 3</Button>
  </StackPanel>
</Page>

請注意,標記中不需要 Children 的 屬性元素,也不需要 UIElementCollection 的 元素。 這是 XAML 的設計特色,可讓以遞歸方式定義 UI 的元素,以更直覺的具有直接父子元素關聯性的巢狀元素樹狀結構呈現,而不需要介入屬性元素標籤或集合物件。 事實上,UIElementCollection 在設計上無法在標記中明確指定為物件元素。 這是因為其唯一的用途是做為隱含集合,所以 UIElementCollection 不會公開公用無參數建構函式,因此無法作為物件元素生成。

混合有內容屬性之物件中的屬性元素和物件元素

XAML 規格表明 XAML 處理器可以強制要求用來填滿物件元素內 XAML 內容屬性的物件元素必須連續,而且不得混合。 WPF XAML 處理器會強制實行這項混合屬性元素和內容的限制。

您可以讓子物件元素成為物件元素內的第一個直接標記。 在此之後您便能引進屬性元素。 或者,您可以指定一或多個屬性元素,然後指定內容,再指定更多屬性元素。 但是,一旦屬性元素跟隨內容,您便無法導入更多內容,只能新增屬性元素。

此內容 / 屬性元素順序要求不適用於做為內容的內部文字。 然而保持內部文字連續仍然是良好的標記習慣,因為如果屬性元素與內部文字在標記中交織在一起,則視覺上很難看見重要空白字元。

XAML 命名空間

上述語法範例都未指定預設 XAML 命名空間以外的 XAML 命名空間。 在一般 WPF 應用程式中,預設的 XAML 命名空間會指定為 WPF 命名空間。 您可以指定預設 XAML 命名空間以外的 XAML 命名空間,但仍使用類似的語法。 但是,在預設 XAML 命名空間中無法存取類別名稱的情況下,該類別名稱前面必須加上與對應 CLR 命名空間對應的 XAML 命名空間前置詞。 例如, <custom:Example/> 是生成 Example 類別執行個體的物件元素語法,其中包含該類別的 CLR 命名空間(以及可能包含支援型別的外部組件資訊)先前已對應至 custom 前置詞。

如需 XAML 命名空間的詳細資訊,請參閱 XAML 命名空間和 WPF XAML 命名空間對應

標記延伸

XAML 會定義標記延伸程式設計實體,以便從字串屬性值或物件元素的一般 XAML 處理器處理程序中逸出,並將處理延遲至支援類別。 使用屬性語法時,識別 XAML 處理器標記延伸的字元是左大括號 ({),後面接著右大括號 (}) 以外的任何字元。 左大括號後面的第一個字串必須參考提供特定擴充行為的類別,如果該子字串是 true 類別名稱的一部分,則參考可以省略子字串 “Extension”。 因此,您可能會看見單一空格,接著擴充實行會使用每個後續字元做為輸入,直到遇到右大括號為止。

.NET XAML 實作使用 MarkupExtension 抽象類型作為 WPF 支援的所有標記延伸以及其他架構或技術的基礎。 WPF 實行的標記延伸通常是為了提供參考其他現有物件的方法,或對將在執行階段評估的物件進行延後參考。 例如,藉由指定 {Binding} 標記延伸來取代特定屬性通常採用的值,即可完成簡單的 WPF 資料系結。 許多 WPF 標記延伸會為屬性啟用屬性語法,否則屬性語法將無法使用。 例如,Style 物件是一種相對複雜的型別,其中包含巢狀物件和屬性系列。 WPF 中的樣式通常會定義為 ResourceDictionary 中的資源,然後透過要求資源的兩個 WPF 標記延伸之一來參考。 標記延伸會將屬性值的評估延後至資源查詢,並啟用提供 Style 屬性值,並採用屬性語法中的類型 Style,如下列範例所示:

<Button Style="{StaticResource MyStyle}">My button</Button>

在本範例中,StaticResource 識別提供標記延伸實行的 StaticResourceExtension 類別。 下一個字串 MyStyle 會作為非預設 StaticResourceExtension 建構函式的輸入,其中從延伸字串取得的參數會宣告所要求的 ResourceKeyMyStyle 應為定義為資源之 Style x:Key 值。 StaticResource 標記延伸 之使用要求資源在載入時透過靜態資源查閱邏輯提供 Style 屬性值。

如需標記延伸的詳細資訊,請參閱標記延伸和 WPF XAML。 如需在一般 .NET XAML 實作中啟用的標記延伸和其他 XAML 程式設計功能的參考,請參閱 XAML Namespace(x:) 語言功能。 WPF 特定的標記延伸相關資訊請參閱 WPF XAML 延伸模組

附加屬性

附加屬性是 XAML 中引進的程式設計概念,可由特定型別擁有和定義屬性,但在任何元素上設定為屬性或屬性元素。 附加屬性的主要使用情境是讓標記結構中的子元素向父元素報告資訊,而不需要跨所有元素廣泛共享的物件模型。 相反地,父元素可以使用附加屬性將資訊報告給子元素。 如需附加屬性用途以及如何建立您自己的附加屬性的詳細資訊,請參閱附加屬性概觀

附加屬性使用外觀上類似於屬性元素語法的語法。在此語法中,您也會指定 typeName.propertyName 組合。 有兩個重大差異:

  • 您甚至可以在透過屬性語法設定附加屬性使用 typeName.propertyName 組合。 附加屬性是屬性語法中唯一需要限定屬性名稱的情況。

  • 您也可以使用附加屬性的屬性元素語法。 不過,針對一般屬性元素語法,您指定的 typeName 是包含屬性元素的物件元素。 如果您參考附加屬性,則定義附加屬性類別的是 typeName,而非包含的物件元素。

附加事件

附加事件是 XAML 中導入的另一個程式設計概念,其中事件可由特定型別定義,但處理常式可以附加在任何物件元素上。 在 WOF 實作中,定義附加事件的型別通常是定義服務的靜態型別,有時這些附加事件會由公開服務的型別中的路由事件別名 (alias) 公開。 附加事件的處理常式是透過屬性語法來指定。 如同附加事件,屬性語法納入了附加事件以允許 typeName.eventName 使用方式,其中 typeName 是提供附加事件基礎結構 AddRemove 事件處理程式存取子的類別,而 eventName為事件名稱。

XAML 根元素的結構

下表顯示一般 XAML 根元素結構,顯示根元素的特定屬性:

屬性 描述
<Page 根元素的起始物件元素
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 預設 (WPF)XAML 命名空間
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" XAML 語言 XAML 命名空間
x:Class="ExampleNamespace.ExampleCode" 將標記連接到針對部分類別定義之任何程式碼後置的部分類別宣告
> 根目錄的物件元素結尾。 物件尚未關閉,因為元素包含子元素

選擇性和不建議的 XAML 使用方式

下列各節說明 XAML 處理器理論上支援的 XAML 使用方式,但會在您開發包含 XAML 來源的應用程式時產生資訊冗餘或其他視覺缺陷,令 XAML 檔案難以閱讀的問題。

選擇性屬性元素使用方式

選擇性的屬性元素使用方式包括明確寫出 XAML 處理器認定為隱含的元素內容屬性。 例如,當您宣告 Menu的內容時,您可以選擇將 MenuItems 集合明確宣告為 <Menu.Items> 屬性元素標記,並將每個 MenuItem 放在 <Menu.Items> 內,而不是使用隱含的 XAML 處理器行為,讓 Menu 的所有子元素都必須是 MenuItem ,並放在 Items 集合中。 有時候選擇性的使用方式有助於以在視覺上釐清標記中所表示的物件結構。 或者,有時候明確的屬性元素使用方式可以避免在技術上可行但視覺上令人困惑的標記,例如屬性值內的巢狀標記延伸。

完整 typeName.memberName 限定屬性

typeName.memberName 格式的屬性實際上比路由事件案例更為通用。 但在其他情境中上述形式是多餘的,若非基於標記樣式和可讀性的原因,您應避免使用。 在下列範例中, Background 屬性的三個參考皆完全相等:

<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>

Button.Background 能運行是因為 Button 屬性的限定查閱成功 (Background 繼承自 Control), Button 是物件元素的類別或基底類別。 Control.Background 能運行是因為 Control 類別實際上定義 Background ,而 ControlButton 基底類別。

不過,下列 typeName.memberName 格式範例無法運作,因此會顯示註解:

<!--<Button Label.Background="Blue">Does not work</Button> -->

Label 是另一個 Control 衍生類別,而且如果您已在 Label 物件元素內指定 Label.Background ,則此使用方式會正常運作。 不過,由於 Label 不是 Button的類別或基底類別,因此指定的 XAML 處理器行為就是將 Label.Background 當作附加屬性來處理。 Label.Background 不是可用的附加屬性,此使用方式因此失敗。

baseTypeName.memberName 屬性元素

typeName.memberName 表單適用於屬性語法的情境類似,baseTypeName.memberName 語法適用於屬性元素語法。 例如,下列語法實際可行:

<Button>Control.Background PE
  <Control.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="Yellow" Offset="0.0" />
      <GradientStop Color="LimeGreen" Offset="1.0" />
    </LinearGradientBrush>
    </Control.Background>
</Button>

在這裡,即使屬性元素包含在 Button 中,屬性元素還是被指定為 Control.Background

但就如屬性使用的 typeName.memberName 格式,baseTypeName.memberName 不是好的標記樣式,您應該避免使用。

另請參閱