您可以在 XAML 架構中建立控制項範本,以自訂控件的視覺結構和視覺行為。 控件有許多屬性,例如 Background、 Foreground 和 FontFamily,您可以設定為指定控件外觀的不同層面。 但是您可以藉由設定這些屬性所做的變更受到限制。 您可以使用 ControlTemplate 類別來建立範本,以指定其他自訂項目。 在這裡,我們會示範如何建立 ControlTemplate 來自定義 CheckBox 控件的外觀。
自定義控件範例
根據預設,CheckBox 控件會將其內容(CheckBox旁的字串或物件)放在勾選方塊的右邊,而勾選標記顯示用戶已選擇了 CheckBox。 這些特性代表 CheckBox 的視覺結構和視覺行為。
以下是使用預設 ControlTemplate 顯示在 、和 Unchecked 狀態中的 Checked。
您可以建立 ControlTemplate 來變更 CheckBox的這些特性。 例如,如果您想要複選框的內容在選取方塊下方,而您想要使用 X 來指出使用者選取複選框。 您可以在 ControlTemplate 的 CheckBox中指定這些特性。
若要搭配控制項使用自定義範本,請將 ControlTemplate 指派給控制項的 Template 屬性。 以下是使用稱為
<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>
以下是此 CheckBox 在套用範本之後的外觀,對應於 Unchecked、Checked和 Indeterminate 狀態。
指定一個控件的視覺結構
當您建立 ControlTemplate 時,您可以結合 FrameworkElement 物件來建置單一控件。 ControlTemplate 必須只有一個 FrameworkElement 做為其根元素。 根元素通常包含其他 FrameworkElement 物件。 對象的組合構成控件的視覺結構。
此 XAML 會建立 CheckBox 的 ControlTemplate,指定控件的內容位於選取方塊下方。 根元素是 Border。 此範例會指定 Path 來建立一個 X,這表示使用者選取了 CheckBox,並建立一個 Ellipse,顯示不確定的狀態。 注意,Opacity 在 Path 和 Ellipse 上預設設定為 0,因此兩者預設情況下不會顯示。
TemplateBinding 是一種特殊的系結,可將控件範本中屬性的值連結到樣板化控件上其他公開屬性的值。 TemplateBinding 只能在 XAML 中的 ControlTemplate 定義中使用。 如需詳細資訊,請參閱 TemplateBinding 標記延伸。
備註
從 Windows 10 版本 1809 開始(SDK 17763),您可以在 您使用 templateBinding的位置使用 x:Bind 標記延伸。 如需詳細資訊,請參閱 TemplateBinding 標記延伸。
<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False"/>
<!-- Create an X to indicate that the CheckBox is selected. -->
<Path x:Name="CheckGlyph"
Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
FlowDirection="LeftToRight"
Height="14" Width="16" Opacity="0" Stretch="Fill"/>
<Ellipse x:Name="IndeterminateGlyph"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
<ContentPresenter x:Name="ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</ControlTemplate>
指定控件的視覺行為
視覺行為會指定控件處於特定狀態時的外觀。
CheckBox 控制件有 3 個檢查狀態:Checked、 Unchecked和 Indeterminate。
IsChecked 屬性的值會決定 核取方塊的狀態,而其狀態會決定方塊中出現的內容。
下表列出 IsChecked的可能值、 CheckBox 的對應狀態,以及 CheckBox 的外觀。
| IsChecked 值 | CheckBox 狀態 | CheckBox 外觀 |
|---|---|---|
| 是 | Checked |
包含 「X」。。 |
| 假 | Unchecked |
空白。 |
| 零 | Indeterminate |
包含圓形。 |
當您使用 VisualState 物件處於特定狀態時,您可以指定控件的外觀。
VisualState 包含 Setter 或 Storyboard,變更 ControlTemplate中項目的外觀。 當控件進入
此 XAML 會顯示 、和 Checked 狀態 Unchecked 物件。 此範例會設定 Indeterminate
VisualState 指定名為 的 Ellipse 之 IndeterminateGlyph 為 1。
Unchecked
VisualState 沒有 Setter 或 Storyboard,因此 CheckBox 會回到其默認外觀。
<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="CheckGlyph.Opacity" Value="1"/>
</VisualState.Setters>
<!-- This Storyboard is equivalent to the Setter. -->
<!--<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity"/>
</Storyboard>-->
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate">
<VisualState.Setters>
<Setter Target="IndeterminateGlyph.Opacity" Value="1"/>
</VisualState.Setters>
<!-- This Storyboard is equivalent to the Setter. -->
<!--<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetName="IndeterminateGlyph" Storyboard.TargetProperty="Opacity"/>
</Storyboard>-->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False"/>
<!-- Create an X to indicate that the CheckBox is selected. -->
<Path x:Name="CheckGlyph"
Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
FlowDirection="LeftToRight"
Height="14" Width="16" Opacity="0" Stretch="Fill"/>
<Ellipse x:Name="IndeterminateGlyph"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
<ContentPresenter x:Name="ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</ControlTemplate>
若要進一步瞭解 VisualState 對象的運作方式,請考慮 CheckBox 從 Unchecked 狀態到 Checked 狀態、 Indeterminate 狀態,然後回到 Unchecked 狀態時會發生什麼情況。 以下是過渡。
| 狀態轉換 | 會發生什麼事 | 轉換完成時的 CheckBox 外觀 |
|---|---|---|
從 Unchecked 到 Checked。 |
Setter 的值會被應用於 CheckedVisualState,因此 的 為 1。 |
一個 X 被顯示出來。 |
從 Checked 到 Indeterminate。 |
Setter 的值會被應用於 IndeterminateVisualState,因此 的 為 1。 會移除 VisualState 的 CheckedSetter 值,因此的不透明度CheckGlyph為 0。 |
隨即顯示圓形。 |
從 Indeterminate 到 Unchecked。 |
Setter 值已移除,因此 IndeterminateVisualState 的 的 為 0。 |
不會顯示任何內容。 |
如需如何建立控件視覺狀態的詳細資訊,特別是如何使用 Storyboard 類別和動畫類型,請參閱 視覺狀態的分鏡腳本動畫。
使用工具輕鬆管理主題設定
將主題套用至控件的快速方法是以滑鼠右鍵點擊 Microsoft Visual Studio 檔案大綱 上的控件,然後選取 [編輯主題] 或 [編輯樣式](視您以滑鼠右鍵點擊的控件而定)。 然後,您可以選取 [ 套用資源 ] 來套用現有的主題,或選取 [ 建立空白] 來定義新的主題。
控制選項和輔助功能
當您為控件建立新的範本時,除了可能變更控件的行為和視覺外觀之外,您可能也會變更控件將本身呈現為輔助功能架構的方式。 Windows 應用程式支援 Microsoft UI 自動化架構的無障礙功能。 所有預設控制項及其範本都支援適用於控制項用途和功能的通用UI自動化控件類型和模式。 這些控制項類型和模式是由UI自動化用戶端解譯,例如輔助技術,這可讓控件成為較大型可存取應用程式UI的一部分。
若要區分基本控制邏輯並滿足 UI 自動化的一些架構需求,控制類別會將其無障礙支援包含在一個稱為自動化對等的單獨類別中。 自動化對應有時會與控制範本互動,因為對應預期範本中會存在某些具名元件,以便啟用輔助技術來觸發按鈕動作等功能。
當您建立全新的自定義控制項時,您有時也會想要建立新的自動化同級控制項與其搭配。 如需詳細資訊,請參閱 自訂自動化合作對象。
深入瞭解控件的預設範本
描述 XAML 控制項樣式和範本的章節會顯示出在先前提到使用的 編輯主題 或 編輯樣式 技巧時可見的相同起始 XAML 的摘錄。 每個主題都會列出視覺狀態的名稱、所使用的主題資源,以及包含範本之樣式的完整 XAML。 如果您已經開始修改範本,並想要查看原始範本的外觀或確認您的新範本是否具備所有必需的具名視覺狀態,這些主題可能會是有用的指南。
控件範本中的主題資源
對於 XAML 範例中的某些屬性,您可能已經注意到使用 {ThemeResource} 標記延伸的資源參考。 這是一種技術,可讓單一控件範本使用資源,視目前作用中的主題而定,這些資源可以是不同的值。 對於筆刷和色彩來說,這特別重要,因為主題的主要目的是讓用戶選擇要套用至整體系統的深色、淺色或高對比度主題。 使用 XAML 資源系統的應用程式可以使用適用於該主題的資源集,讓應用程式 UI 中的主題選擇反映使用者的全系統主題選擇。