本文件定義用來描述 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 屬性不是在 Button 類別上直接宣告的屬性。 相反地,Background 是從基底 Control 類別繼承而來。
WPF XAML 元素的類別繼承行為,明顯不同於結構描述所強制的 XML 標記詮釋方式。 類別繼承有時相當複雜,特別是當中繼基本類別較抽象,或涉及介面時。 這就是 XAML 元素及其允許屬性的集合難以使用 XML 程式設計中通常採用的結構描述類型(例如 DTD 或 XSD 格式)來準確且完整地表示的其中一個原因。 另一個原因是 XAML 語言本身的擴充性和型別對應功能排除了允許型別和成員之任何固定表示法的完整性。
物件元素語法
物件元素語法 是 XAML 標記語法,可藉由宣告 XML 元素來生成 CLR 類別或結構。 此語法類似於 HTML 等其他標記語言的元素語法。 物件元素語法的開頭是左角括弧 (<),後面緊接著要生成的類別或結構的型別名稱。 零個或多個空格可以接在型別名稱之後,而對象元素亦可宣告零個或多個屬性,其中一或多個空格會分隔每個屬性名稱 =“value” 組。 最後,需有至少下列任一情況為真:
元素和標籤必須以正斜線 (/) 後方緊接一個右尖括號來閉合(>)。
起始標籤必須以右尖括號完成(>)。 其他物件元素、屬性 (property) 元素或內部文字可以接在起始標籤之後。 此處可包含的內容通常受限於元素的物件模型。 物件元素對應的結束標籤也必須存在,且須具有正確的巢狀結構,並與其他起始與結束標籤配對保持平衡。
.NET 所實作的 XAML 有一套規則,會將物件元素對應至型別、將 attribute 對應至屬性或事件,並將 XAML 命名空間對應至 CLR 命名空間以及組件。 就 WPF 和 .NET,XAML 物件元素會對應至參考組件中所定義的 .NET 型別,而屬性會對應至這些型別的成員。 當您在 XAML 中參考 CLR 型別時,您也可以存取該型別的繼承成員。
例如,下列範例為物件元素語法,會具現化 Button 類別的新執行個體,並指定 Name 屬性及其值:
<Button Name="CheckoutButton"/>
下列範例是物件元素語法,也包含 XAML 內容屬性 (property) 語法。 其中包含的文字將用於設定 TextBox 的 XAML 內容屬性 Text。
<TextBox>This is a Text Box</TextBox>
內容模型
一個類別在語法方面可能可做為 XAML 物件元素使用,但該元素只有在放置在整體內容模型或元素樹狀結構的預期位置時,才會在應用程式或頁面中正常運作。 例如,MenuItem 通常只應放置為 MenuBase 衍生類別的子項,例如 Menu。 特定元素的內容模型,記錄於控制項及其他可作為 XAML 元素之 WPF 類別頁面中的備註部分。
物件元素的屬性 (property)
XAML 中的屬性 (property) 可由多種語法設定。 根據您所設定之屬性的基礎型別系統特性,特定屬性可以使用哪一種語法會有所不同。
藉由設定屬性 (property) 值,您可以為物件新增功能或特性,因為它們存在於執行階段物件圖中。 自物件元素建立之物件的初始狀態是以無參數建構函式行為作為基礎。 一般而言,您的應用程式通常不會使用任何特定物件的完全預設實例。
屬性語法(屬性)
屬性語法是藉由在現有物件元素上宣告屬性來設定屬性 (property) 值的 XAML 標記語法。 屬性名稱必須與對應相應物件元素之類別屬性 (property) 的 CLR 成員名稱對應。 屬性名稱後接指派運算符 (=)。 屬性值必須是以引號括住的字串。
備註
您可以使用交替引號,在屬性內放置常值引號。 例如,您可以使用單引號宣告包含雙引號字元的字串。 無論您使用單引號還是雙引號,都應該使用成對的符號來起始和結束屬性值字串。 任何特定 XAML 語法的字元限制也得透過逸出序列或其他技巧來迴避。 請參閱 XML 字元實體與 XAML。
若要透過屬性語法設定屬性 (property),其必須為公用且可寫入的屬性。 基礎型別系統中屬性的值必須是值型別,或必須是可在存取相關基礎型別時由 XAML 處理器具現化或參照的參考型別。
對於 WPF XAML 事件,作為屬性名稱所參考的事件必須是公用的,且具有公用委派。
屬性或事件必須是由所包含之物件元素生成的類別或結構成員。
屬性值的處理
XAML 處理器會處理開頭和結尾引號中包含的字串值。 就屬性 (property) 而言,預設處理方式取決於其基礎 CLR 屬性類別。
屬性值會依照以下處理順序,由下列其中之一填入:
如果 XAML 處理器遇到大括弧字元,或遇到衍生自 MarkupExtension 的物件元素,則會先評估所參考的標記延伸,而不是將該值當作字串處理,並使用標記延伸所傳回的物件作為該值。 在許多情況下,標記延伸所傳回的物件可能是對現有物件的參考,或是將求值延後到執行階段的運算式,而不是新建立的物件。
如果該屬性是使用具屬性的 TypeConverter 宣告,或該屬性的值型別是使用具屬性的 TypeConverter 宣告,則該屬性的字串值會作為轉換輸入提交給型別轉換器,而轉換器會傳回新的物件執行個體。
如果沒有 TypeConverter,則會嘗試直接轉換為屬性型別。 這個最後一個層級,是在 XAML 語言基本型別之間直接以剖析器原生值進行轉換,或檢查列舉中具名常數的名稱(接著由剖析器取得對應的值)。
列舉型屬性值
XAML 中的列舉是由 XAML 剖析器以內建函式處理,而列舉的成員應該藉由指定列舉的其中一個具名常數的字串名稱來指定。
對於非標幟列舉值,原生行為是處理屬性值的字串,並將其剖析為其中一個列舉值。 您不會像在程式碼中那樣,以 Enumeration.Value 格式指定列舉值。 相反地,您只需指定 Value,而 Enumeration 會根據您所設定屬性的類型推斷出來。 如果您以 Enumeration.Value 的形式指定屬性,將無法正確解析。
對於旗標列舉,其行為是以 Enum.Parse 方法為基礎。 您可以藉由以逗號分隔每個值,為標幟列舉指定多個值。 不過,您無法合併非標幟的列舉值。 例如,您無法使用逗號語法來嘗試建立一個根據非旗標列舉的多個條件運作的 Trigger:
<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
<Setter ... />
</Trigger>
...
在 WPF 中,支援可在 XAML 中設定之屬性的旗標列舉並不常見。 不過,其中一個這樣的列舉是 StyleSimulations。 例如,您可以使用以逗號分隔的旗標式屬性語法,修改在 Glyphs 類別的備註中提供的範例;StyleSimulations = "BoldSimulation" 可以變成 StyleSimulations = "BoldSimulation,ItalicSimulation"。
KeyBinding.Modifiers 是另一個可指定一個以上列舉值的屬性。 不過,這個屬性剛好是個特例,因為 ModifierKeys 列舉支援自己的型別轉換器。 修飾符的型別轉換器會使用加號 (+) 做為分隔符,而不是逗號 (,)。 這項轉換支援更傳統的語法,以代表 Microsoft Windows 程式設計中的按鍵組合,例如 “Ctrl+Alt”。
屬性與事件成員名稱參考資料
指定屬性時,您可以參照任何屬性或事件,只要它是您為包含物件元素所執行個體化之 CLR 型別的成員。
或者,您可以參考與包含的物件元素無關之附加屬性或附加事件。 (附加屬性將於後續章節中討論。)
您也可以使用 typeName.event 這種部分限定名稱,來命名任何可透過預設命名空間存取之物件的任何事件;此語法支援為路由事件附加處理常式,其中處理常式旨在處理由子元素路由而來的事件,但父元素本身在其成員表中並沒有該事件。 此語法類似於附加事件語法,但這裡的事件不是真正的附加事件。 相反地,您參照的是以限定名稱表示的事件。 如需詳細資訊,請參閱路由事件概觀。
在某些情況下,屬性 (property) 名稱有時會以屬性的值提供,而不是屬性名稱。 該屬性名稱也可以包含限定符,例如以 ownerType.dependencyPropertyName 形式指定的屬性。 以 XAML 撰寫樣式或範本時,這種情況很常見。 以屬性值提供之屬性名稱的處理規則不同,而且會受所設定之屬性的型別或特定 WPF 子系統的行為所控管。 如需詳細資訊,請參閱 樣式與範本。
屬性名稱的另一個用法是當屬性值描述屬性—屬性關聯性時。 此功能用於資料繫結和分鏡目標,並由 PropertyPath 類別及其型別轉換器啟用。 如需更完整的查閱語意說明,請參閱 PropertyPath XAML Syntax。
屬性元素語法
屬性 (Property) 元素語法 是與元素的基本 XML 語法規則有些差異的語法。 在 XML 中,屬性的值是事實字串,唯一可能的變化是使用字串編碼格式。 在 XAML 中,您可以將其他物件元素指派為屬性的值。 這項功能透過屬性元素語法實現。 屬性不是在元素標籤內以屬性的形式指定,而是使用 elementTypeName.propertyName 形式的開啟元素標籤來指定,並在其中指定該屬性的值,然後再關閉該屬性元素。
具體而言,該語法以左尖括號 (<) 開始,後面緊接著是包含該屬性元素語法之類別或結構的型別名稱。 其後緊接著是一個點 (.),然後是屬性的名稱,接著是右尖括號 (>)。 如同屬性語法,該屬性 (property) 必須存在於指定型別的宣告公用成員內。 要指派給屬性的值包含在屬性元素內。 一般而言,此值會以一個或多個物件元素的形式給定,因為將物件指定為值便是屬性元素語法欲處理的情境。 最後,必須提供對應的結束標籤,並指定相同的 elementTypeName.propertyName 組合,且與其他元素標籤保持適當的巢狀關係與配對平衡。
例如,以下為 Button 之 ContextMenu 屬性的屬性元素語法。
<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 Directive 套用於屬性元素,從而將其中的值標記為應在 WPF 輸出 BAML 或透過其他技術進行本地化的值。
WPF 邏輯樹狀結構中不會表示屬性元素。 屬性元素只是設定屬性的特定語法,而且不是具有實例或物件支援的元素。 (如需邏輯樹概念的詳細資訊,請參閱 WPF 中的樹狀結構。)
對於同時支援屬性 (attribute) 和屬性 (property) 元素語法的屬性,這兩個語法通常會有相同的結果,不過空白字元處理等細微差別在兩者之間可能會稍有不同。
集合語法
XAML 規格需要 XAML 處理器實作,以識別實值型別為集合的屬性。 .NET 中一般 XAML 處理器實作是以受控碼和 CLR 為基礎,並透過下列其中一項來識別集合型別:
型別實作 IList。
型別會實作 IDictionary。
型別衍生自 Array(如需 XAML 中陣列的詳細資訊,請參閱 x:Array 標記延伸模組。)
如果屬性的型別是集合,則推斷的集合型別不需要在標記中指定為物件元素。 相反地,欲納入集合中的元素會指定為屬性元素的一個或多個子元素。 每個此類項目都會在載入時評估為物件,並透過呼叫隱含集合的 Add 方法加入該集合。 例如,Style 的 Triggers 屬性採用特殊化集合類型 TriggerCollection,並實作 IList。 不需要在標記語法中具現化 TriggerCollection 物件元素。 相反地,您可以將一個或多個 Trigger 項目指定為 Style.Triggers 屬性元素內的元素,其中 Trigger (或衍生類別) 是強型別且隱含的 TriggerCollection 所預期的項目型別。
<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>
這基本上是不合法的,因為如果透過用於 content 屬性的屬性元素語法將此語法明確寫出來,那麼 content 屬性就會被設定兩次:
<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 衍生類別都會將 XAML 內容屬性設定為 Children,其需要型別為 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 建構函式的輸入,其中從延伸字串取得的參數會宣告所要求的 ResourceKey。
MyStyle 應為定義為資源的 Style 之 x:Key 值。
StaticResource 標記延伸 的用法要求在載入時透過靜態資源查閱邏輯,使用該資源來提供 Style 屬性值。
如需更多有關標記延伸的資訊,請參閱 標記延伸與 WPF XAML。 如需參考一般 .NET XAML 實作中支援的標記延伸模組及其他 XAML 程式設計功能,請參閱 XAML 命名空間 (x:) 語言功能。 如需 WPF 特定的標記延伸,請參閱 WPF XAML 延伸。
附加屬性
附加屬性是 XAML 中引進的程式設計概念,可由特定型別擁有和定義屬性,但在任何元素上設定為屬性或屬性元素。 附加屬性的主要使用情境是讓標記結構中的子元素向父元素報告資訊,而不需要跨所有元素廣泛共享的物件模型。 相反地,父元素可以使用附加屬性將資訊報告給子元素。 如需了解附加屬性的目的以及如何建立您自己的附加屬性,請參閱 附加屬性概觀。
附加屬性使用的語法在表面上類似於屬性元素語法,因為您同樣會指定 typeName.propertyName 的組合。 有兩個重大差異:
您即使在透過屬性語法設定附加屬性時,也可以使用 typeName.propertyName 組合。 附加屬性是屬性語法中唯一需要限定屬性名稱的情況。
您也可以使用屬性元素語法來指定附加屬性。 不過,針對一般屬性元素語法,您指定的 typeName 是包含屬性元素的物件元素。 如果您指的是附加屬性,則 typeName 是定義該附加屬性的類別,而不是包含該屬性的物件項目。
附加事件
附加事件是 XAML 中導入的另一個程式設計概念,其中事件可由特定型別定義,但處理常式可以附加在任何物件元素上。 在 WPF 實作中,定義附加事件的類型通常是靜態類型,定義服務,有時這些附加事件會透過路由事件別名暴露服務。 附加事件的處理常式是透過屬性語法來指定。 如同附加屬性一樣,附加事件的屬性語法也已擴充,可使用 typeName.eventName 的用法,其中 typeName 是為附加事件基礎結構提供 Add 和 Remove 事件處理常式存取子的類別,而 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 的內容時,您可以選擇將 Menu 的 Items 集合明確宣告為 <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,而 Control 是 Button 的基底類別。
不過,下列 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 在標記中也是不佳的寫法,應避免這樣做。
另請參閱
- WPF 中的 XAML
- XAML 命名空間 (x:) 語言功能
- WPF XAML 擴充功能
- 相依性屬性概觀
- 型別轉換器與 XAML
- WPF 的 XAML 和自訂類別