WPF換膚設(shè)計(jì)原理淺析
WPF換膚的設(shè)計(jì)原理,利用資源字典為每種皮膚資源添加不同的樣式,在后臺(tái)切換皮膚資源文件。
截圖

上圖中,第一張圖采用規(guī)則樣式,第二張圖采用不規(guī)則樣式,截圖的時(shí)候略有瑕疵。
資源字典
規(guī)則樣式資源Skin.RegularStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--Window樣式-->
<Style x:Key="WindowStyle" TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Green" Offset="0"></GradientStop>
<GradientStop Color="LightGreen" Offset="0.4"></GradientStop>
<GradientStop Color="White" Offset="1"></GradientStop>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Button樣式-->
<Style TargetType="Button">
<Setter Property="Width" Value="70"></Setter>
<Setter Property="Height" Value="23"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="bdr" Cursor="Arrow"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="White" Offset="0"></GradientStop>
<GradientStop Color="LightGreen" Offset="0.3"></GradientStop>
<GradientStop Color="Green" Offset="1"></GradientStop>
</LinearGradientBrush>
</Border.Background>
<TextBlock Name="tbk" Background="Transparent" Foreground="DarkGreen" TextAlignment="Center"
Text="{TemplateBinding Content}"></TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bdr" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="LightGreen" Offset="0"></GradientStop>
<GradientStop Color="Green" Offset="1"></GradientStop>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="tbk" Property="Foreground" Value="White"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TextBox樣式-->
<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="SketchFlow Print"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border BorderBrush="DarkGreen" BorderThickness="0.5">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"></ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--ContextMenu樣式-->
<Style TargetType="ContextMenu">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border BorderBrush="Green" BorderThickness="1">
<ItemsPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--MenuItem樣式-->
<Style TargetType="MenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Border Name="border" Background="LightGreen" BorderThickness="0">
<TextBlock Name="tbk" Background="Transparent" Padding="5,5"
Text="{TemplateBinding Header}"></TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="Green"></Setter>
<Setter TargetName="tbk" Property="Foreground" Value="White"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TextBlock樣式-->
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="SketchFlow Print"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</ResourceDictionary>
不規(guī)則樣式資源Skin.RoundedCornerStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--Window樣式-->
<Style x:Key="WindowStyle" TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Grid Margin="10">
<Rectangle Fill="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
RadiusX="5" RadiusY="5">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="10" Color="Black" Direction="0" Opacity="0.8"
RenderingBias="Performance" ShadowDepth="0"/>
</Rectangle.Effect>
</Rectangle>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True" CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Blue" Offset="0"></GradientStop>
<GradientStop Color="LightBlue" Offset="0.4"></GradientStop>
<GradientStop Color="White" Offset="1"></GradientStop>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter></ContentPresenter>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Button樣式-->
<Style TargetType="Button">
<Setter Property="Width" Value="70"></Setter>
<Setter Property="Height" Value="23"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="bdr" CornerRadius="5" Cursor="Hand"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock Name="tbk" Background="Transparent" Foreground="Yellow" TextAlignment="Center"
Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"></TextBlock>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="White" Offset="0"></GradientStop>
<GradientStop Color="LightBlue" Offset="0.3"></GradientStop>
<GradientStop Color="Blue" Offset="1"></GradientStop>
</LinearGradientBrush>
</Border.Background>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bdr" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="LightBlue" Offset="0"></GradientStop>
<GradientStop Color="Blue" Offset="1"></GradientStop>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="tbk" Property="Foreground" Value="LightYellow"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TextBox樣式-->
<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="Times New Roman"></Setter>
<Setter Property="FontSize" Value="14"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border BorderBrush="Blue" BorderThickness="0.5" CornerRadius="5">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"></ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--ContextMenu樣式-->
<Style TargetType="ContextMenu">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border CornerRadius="5" BorderBrush="Blue" BorderThickness="1">
<ItemsPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--MenuItem樣式-->
<Style TargetType="MenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Border Name="border" Background="LightSkyBlue" BorderThickness="0" CornerRadius="5">
<TextBlock Name="tbk" Background="Transparent" Padding="5,5"
Text="{TemplateBinding Header}"></TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="BlueViolet"></Setter>
<Setter TargetName="tbk" Property="Foreground" Value="White"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TextBlock樣式-->
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="Times New Roman"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</ResourceDictionary>
仔細(xì)觀察上面定義的樣式,你會(huì)發(fā)現(xiàn)在定義Window樣式的時(shí)候指定了Key,其他的Control樣式卻沒(méi)有指定Key。大家都知道,如果沒(méi)有給Style指定Key,那么這個(gè)Style會(huì)應(yīng)用到所有目標(biāo)類(lèi)型(TargetType)為指定類(lèi)型的Control。請(qǐng)看下面一段文字:

因?yàn)樵趽Q膚的過(guò)程中,需要?jiǎng)討B(tài)加載Window的樣式,所以用DynamicResource作綁定Style="{DynamicResource WindowStyle}"。
App.xaml
程序運(yùn)行的時(shí)候,默認(rèn)加載規(guī)則樣式的皮膚。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary\Skin.RegularStyle.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
后臺(tái)代碼
/// <summary>
/// MenuItem的執(zhí)行方法
/// </summary>
/// <param name="parameter"></param>
private void RelayMenuItemEvent(object parameter)
{
if (parameter.ToString() == RegularStyle)
{
ChangeSkinResource(Skins[0]);
}
else if (parameter.ToString() == RoundedCornerStyle)
{
ChangeSkinResource(Skins[1]);
}
}
/// <summary>
/// 更換皮膚資源
/// </summary>
/// <param name="skin"></param>
private void ChangeSkinResource(ResourceDictionary skin)
{
if (Application.Current.Resources.MergedDictionaries[0].Source.IsAbsoluteUri)
{
if (Application.Current.Resources.MergedDictionaries[0].Source.OriginalString != skin.Source.OriginalString)
{
Application.Current.Resources.MergedDictionaries[0] = skin;
}
}
else
{
if (Application.Current.Resources.MergedDictionaries[0].Source.OriginalString.ToString('\\') != skin.Source.OriginalString.ToString('/'))
{
Application.Current.Resources.MergedDictionaries[0] = skin;
}
}
}
運(yùn)行的時(shí)候在MainWindow上右鍵選擇皮膚樣式,就可以換膚了。
源碼下載:http://xiazai.jb51.net/201610/yuanma/WPFSkin(jb51.net).rar
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- asp.net簡(jiǎn)單實(shí)現(xiàn)頁(yè)面換膚的方法
- jQuery之網(wǎng)頁(yè)換膚實(shí)現(xiàn)代碼
- JQuery 網(wǎng)站換膚功能實(shí)現(xiàn)代碼
- Javascript結(jié)合css實(shí)現(xiàn)網(wǎng)頁(yè)換膚功能
- js動(dòng)態(tài)修改整個(gè)頁(yè)面樣式達(dá)到換膚效果
- javascript實(shí)現(xiàn)動(dòng)態(tài)CSS換膚技術(shù)的腳本
- 使用jQuery實(shí)現(xiàn)的網(wǎng)頁(yè)版的個(gè)人簡(jiǎn)歷(可換膚)
- 采用XHTML和CSS設(shè)計(jì)可重用可換膚的WEB站點(diǎn)的方法
- 漂亮的widgets,支持換膚和后期開(kāi)發(fā)新皮膚
- js+css簡(jiǎn)單實(shí)現(xiàn)網(wǎng)頁(yè)換膚效果
相關(guān)文章
C#實(shí)現(xiàn)密碼驗(yàn)證與輸錯(cuò)密碼賬戶鎖定
這篇文章介紹了C#實(shí)現(xiàn)密碼驗(yàn)證與輸錯(cuò)密碼賬戶鎖定的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
C#實(shí)現(xiàn)啟動(dòng)項(xiàng)管理的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)啟動(dòng)項(xiàng)管理,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以了解一下2022-12-12
C#使用NOPI庫(kù)實(shí)現(xiàn)導(dǎo)入Excel文檔
NPOI中N指代的是.Net,POI是一個(gè)完全開(kāi)源的Java寫(xiě)成的庫(kù),能夠在沒(méi)有安裝微軟Office或者相應(yīng)環(huán)境的情況下讀寫(xiě)Excel、Word等微軟OLE2組件文檔,幾乎支持所有的Office97~Office2007的文件格式。所以NPOI就是POI項(xiàng)目的.Net版本。2017-05-05
HighCharts圖表控件在ASP.NET WebForm中的使用總結(jié)(全)
這篇文章主要介紹了HighCharts圖表控件在ASP.NET WebForm中的使用總結(jié)(全),需要的朋友可以參考下2015-08-08
使用C#程序驗(yàn)證系統(tǒng)登錄用戶與目錄權(quán)限
這篇文章主要介紹了使用C#程序驗(yàn)證系統(tǒng)登錄用戶與目錄權(quán)限,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12

