如何建立控制項的樣式 (WPF .NET)
使用 Windows Presentation Foundation (WPF),您可以使用自己的可重複使用樣式來自訂現有控制項的外觀。 樣式可以全域套用至您的應用程式、視窗和頁面,或直接套用至控制項。
重要
.NET 7 和 .NET 6 的桌面指南檔正在建置中。
建立樣式
您可以將 視為 Style 將一組屬性值套用至一或多個元素的便利方式。 您可以在任何衍生自 FrameworkElement 或 例如 Window 或 FrameworkContentElementButton 的專案上使用樣式。
宣告樣式的最常見方式是作為 XAML 檔案區 Resources
段中的資源。 因為樣式是資源,所以會遵守套用至所有資源的相同範圍規則。 簡單地說,宣告樣式會影響套用樣式的位置。 例如,如果您在應用程式定義 XAML 檔案的根項目中宣告樣式,則可以在應用程式中的任何位置使用樣式。
<Application x:Class="IntroToStylingAndTemplating.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:IntroToStylingAndTemplating"
StartupUri="WindowExplicitStyle.xaml">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="Header1" TargetType="TextBlock">
<Setter Property="FontSize" Value="15" />
<Setter Property="FontWeight" Value="ExtraBold" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
如果您在其中一個應用程式的 XAML 檔案中宣告樣式,則樣式只能在該 XAML 檔案中使用。 如需資源範圍規則的詳細資訊,請參閱 XAML 資源 概觀。
<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IntroToStylingAndTemplating"
mc:Ignorable="d"
Title="WindowSingleResource" Height="450" Width="800">
<Window.Resources>
<Style x:Key="Header1" TargetType="TextBlock">
<Setter Property="FontSize" Value="15" />
<Setter Property="FontWeight" Value="ExtraBold" />
</Style>
</Window.Resources>
<Grid />
</Window>
樣式是由 <Setter>
套用樣式之專案上設定屬性的子專案所組成。 在上述範例中,請注意,樣式會設定為透過 TargetType
屬性套用至 TextBlock
類型。 樣式會將 設定為 15
,並將 FontWeight 設定 FontSize 為 ExtraBold
。 <Setter>
針對每個屬性新增 樣式變更的 。
隱含套用樣式
Style是將一組屬性值套用至多個元素的便利方式。 例如,請考慮下列 TextBlock 元素及其在視窗中的預設面板。
<StackPanel>
<TextBlock>My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>
您可以直接在每個元素上 TextBlock 設定 屬性,例如 FontSize 和 FontFamily ,來變更預設面板。 不過,如果您想要讓 TextBlock 元素共用某些屬性,您可以在 XAML 檔案的 區段中建立 StyleResources
,如下所示。
<Window.Resources>
<!--A Style that affects all TextBlocks-->
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</Window.Resources>
當您將樣式的 設定 TargetType 為 TextBlock 類型並省略 x:Key
屬性時,樣式會套用至限定為樣式的所有 TextBlock 專案,這通常是 XAML 檔案本身。
現在元素 TextBlock 會顯示如下。
明確套用樣式
如果您將具有值的屬性新增 x:Key
至樣式,樣式就不會再隱含地套用至 的所有專案 TargetType 。 只有明確參考樣式的專案才會套用樣式。
以下是上一節的樣式,但以 x:Key
屬性宣告。
<Window.Resources>
<Style x:Key="TitleText" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</Window.Resources>
若要套用樣式,請使用 StaticResource 標記延伸 ,將 元素上的 屬性設定 Style 為 x:Key
值,如下所示。
<StackPanel>
<TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>
請注意,第一個專案已套用樣式,而第二個 TextBlock TextBlock 元素則保持不變。 上一節的隱含樣式已變更為宣告屬性的 x:Key
樣式,這表示受樣式影響的唯一元素就是直接參考樣式的專案。
一旦套用樣式,明確或隱含地套用樣式,它就會變成密封且無法變更。 如果您想要變更已套用的樣式,請建立新的樣式來取代現有的樣式。 如需詳細資訊,請參閱 IsSealed 屬性 (Property)。
您可以建立一個物件來根據自訂邏輯選擇要套用的樣式。 如需範例,請參閱為 StyleSelector 類別提供的範例。
以程式設計方式套用樣式
若要以程式設計方式將具名樣式指派給專案,請從資源集合取得樣式,並將它指派給元素的 Style 屬性。 資源集合中的專案類型為 Object 。 因此,您必須先將擷取的樣式 System.Windows.Style 轉換成 ,再將它指派給 Style
屬性。 例如,下列程式碼會將名為 textblock1
的 TextBlock
樣式設定為定義的樣式 TitleText
。
textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)
擴充樣式
也許您想要讓兩 TextBlock 個元素共用一些屬性值,例如 FontFamily 和 置中 HorizontalAlignment 。 但您也想要文字[ 我的圖片 ] 有一些額外的屬性。 您可以建立以第一個樣式為基礎的新樣式,如下所示。
<Window.Resources>
<!-- .... other resources .... -->
<!--A Style that affects all TextBlocks-->
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
<!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="TextBlock"
x:Key="TitleText">
<Setter Property="FontSize" Value="26"/>
<Setter Property="Foreground">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#90DDDD" />
<GradientStop Offset="1.0" Color="#5BFFFF" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
<TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>
此 TextBlock
樣式現在置中,會使用 Comic Sans MS
大小為 的 26
字型,並將前景色彩設定為 LinearGradientBrush 範例中顯示的 。 請注意,它會覆寫 FontSize 基底樣式的值。 如果 中 StyleSetter
有多個 Setter 指向相同屬性,則最後宣告的 會優先使用 。
下列顯示 TextBlock 專案現在的外觀:
此 TitleText
樣式會擴充為 型別所建立的 TextBlock 樣式,以 BasedOn="{StaticResource {x:Type TextBlock}}"
參考。 您也可以使用 x:Key
樣式的 來擴充具有 x:Key
的樣式。 例如,如果有名為 Header1
的樣式,而您想要擴充該樣式,您可以使用 BasedOn="{StaticResource Header1}"
。
TargetType 屬性和 x:Key 屬性的關聯性
如先前所示,將 屬性設定 TargetType 為 TextBlock
而不指派樣式,會導致將樣式 x:Key
套用至所有 TextBlock 專案。 在此情況下,x:Key
會隱含地設定為 {x:Type TextBlock}
。 這表示如果您明確將值設定 x:Key
為 以外的 {x:Type TextBlock}
任何專案, Style 則 不會自動套用至所有 TextBlock
專案。 相反地,您必須將樣式(使用 x:Key
值)明確套用至 TextBlock
元素。 如果您的樣式位於 resources 區段,而且您未在樣式上設定 TargetType
屬性,則必須設定 x:Key
屬性。
除了提供 的預設值 x:Key
之外, TargetType
屬性也會指定 setter 屬性套用的型別。 如果您未指定 TargetType
,則必須使用 語法 Property="ClassName.Property"
來限定 物件中的 Setter 屬性與類別名稱。 例如,您必須將 設定為 或 ,而不是設定 Property="FontSize"
Property 。 "TextBlock.FontSize"
"Control.FontSize"
另請注意,許多 WPF 控制項是由其他 WPF 控制項的組合所組成。 如果您建立一個套用到某個型別所有控制項的樣式,可能會獲得非預期的結果。 例如,如果您建立以 中型別為目標的 TextBlock 樣式,則樣式會套用至視窗中的所有 TextBlock
控制項,即使 TextBlock
是另一個控制項的一部分,例如 ListBox 。 Window
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應