WPF之换肤

WPF之换肤

设计原理

WPF换肤的设计原理,利用资源字典为每种皮肤资源添加不同的样式,在后台切换皮肤资源文件。

截图

WPF之换肤

上图中,第一张图采用规则样式,第二张图采用不规则样式,截图的时候略有瑕疵。

资源字典

规则样式资源Skin.RegularStyle.xaml

  1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  2                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  3 

  4     <!--Window样式-->

  5     <Style x:Key="WindowStyle" TargetType="Window">

  6         <Setter Property="Template">

  7             <Setter.Value>

  8                 <ControlTemplate TargetType="Window">

  9                     <Border BorderBrush="{TemplateBinding BorderBrush}" 

 10                             BorderThickness="{TemplateBinding BorderThickness}">

 11                         <Border.Background>

 12                             <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 13                                 <GradientStop Color="Green" Offset="0"></GradientStop>

 14                                 <GradientStop Color="LightGreen" Offset="0.4"></GradientStop>

 15                                 <GradientStop Color="White" Offset="1"></GradientStop>

 16                             </LinearGradientBrush>

 17                         </Border.Background>

 18                         <ContentPresenter></ContentPresenter>

 19                     </Border>

 20                 </ControlTemplate>

 21             </Setter.Value>

 22         </Setter>

 23     </Style>

 24 

 25     <!--Button样式-->

 26     <Style TargetType="Button">

 27         <Setter Property="Width" Value="70"></Setter>

 28         <Setter Property="Height" Value="23"></Setter>

 29         <Setter Property="Template">

 30             <Setter.Value>

 31                 <ControlTemplate TargetType="Button">

 32                     <Border Name="bdr" Cursor="Arrow"

 33                             BorderBrush="{TemplateBinding BorderBrush}" 

 34                             BorderThickness="{TemplateBinding BorderThickness}">

 35                         <Border.Background>

 36                             <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 37                                 <GradientStop Color="White" Offset="0"></GradientStop>

 38                                 <GradientStop Color="LightGreen" Offset="0.3"></GradientStop>

 39                                 <GradientStop Color="Green" Offset="1"></GradientStop>

 40                             </LinearGradientBrush>

 41                         </Border.Background>

 42                         <TextBlock Name="tbk" Background="Transparent" Foreground="DarkGreen" TextAlignment="Center"

 43                                    Text="{TemplateBinding Content}"></TextBlock>

 44                     </Border>

 45                     <ControlTemplate.Triggers>

 46                         <Trigger Property="IsMouseOver" Value="True">

 47                             <Setter TargetName="bdr" Property="Background">

 48                                 <Setter.Value>

 49                                     <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 50                                         <GradientStop Color="LightGreen" Offset="0"></GradientStop>

 51                                         <GradientStop Color="Green" Offset="1"></GradientStop>

 52                                     </LinearGradientBrush>

 53                                 </Setter.Value>

 54                             </Setter>

 55                             <Setter TargetName="tbk" Property="Foreground" Value="White"></Setter>

 56                         </Trigger>

 57                     </ControlTemplate.Triggers>

 58                 </ControlTemplate>

 59             </Setter.Value>

 60         </Setter>

 61     </Style>

 62 

 63     <!--TextBox样式-->

 64     <Style TargetType="TextBox">

 65         <Setter Property="FontFamily" Value="SketchFlow Print"/>

 66         <Setter Property="FontSize" Value="14"/>

 67         <Setter Property="Template">

 68             <Setter.Value>

 69                 <ControlTemplate TargetType="TextBox">

 70                     <Border BorderBrush="DarkGreen" BorderThickness="0.5">

 71                         <ScrollViewer x:Name="PART_ContentHost" Focusable="false" 

 72                                       HorizontalScrollBarVisibility="Hidden" 

 73                                       VerticalScrollBarVisibility="Hidden"></ScrollViewer>

 74                     </Border>

 75                 </ControlTemplate>

 76             </Setter.Value>

 77         </Setter>

 78     </Style>

 79 

 80     <!--ContextMenu样式-->

 81     <Style TargetType="ContextMenu">

 82         <Setter Property="Template">

 83             <Setter.Value>

 84                 <ControlTemplate TargetType="ContextMenu">

 85                     <Border BorderBrush="Green" BorderThickness="1">

 86                         <ItemsPresenter/>

 87                     </Border>

 88                 </ControlTemplate>

 89             </Setter.Value>

 90         </Setter>

 91     </Style>

 92 

 93     <!--MenuItem样式-->

 94     <Style TargetType="MenuItem">

 95         <Setter Property="Template">

 96             <Setter.Value>

 97                 <ControlTemplate TargetType="MenuItem">

 98                     <Border Name="border" Background="LightGreen" BorderThickness="0">

 99                         <TextBlock Name="tbk" Background="Transparent" Padding="5,5"

100                                    Text="{TemplateBinding Header}"></TextBlock>

101                     </Border>

102                     <ControlTemplate.Triggers>

103                         <Trigger Property="IsMouseOver" Value="True">

104                             <Setter TargetName="border" Property="Background" Value="Green"></Setter>

105                             <Setter TargetName="tbk" Property="Foreground" Value="White"></Setter>

106                         </Trigger>

107                     </ControlTemplate.Triggers>

108                 </ControlTemplate>

109             </Setter.Value>

110         </Setter>

111     </Style>

112 

113     <!--TextBlock样式-->

114     <Style TargetType="TextBlock">

115         <Setter Property="FontFamily" Value="SketchFlow Print"/>

116         <Setter Property="FontSize" Value="14"/>

117     </Style>

118 

119 </ResourceDictionary>
View Code

不规则样式资源Skin.RoundedCornerStyle.xaml

  1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  2                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  3 

  4     <!--Window样式-->

  5     <Style x:Key="WindowStyle" TargetType="Window">

  6         <Setter Property="Template">

  7             <Setter.Value>

  8                 <ControlTemplate TargetType="Window">

  9                     <Grid Margin="10">

 10                         <Rectangle Fill="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"  

 11                                    RadiusX="5" RadiusY="5">

 12                             <Rectangle.Effect>

 13                                 <DropShadowEffect BlurRadius="10" Color="Black" Direction="0" Opacity="0.8"

 14                                                   RenderingBias="Performance" ShadowDepth="0"/>

 15                             </Rectangle.Effect>

 16                         </Rectangle>

 17                         <Border BorderBrush="{TemplateBinding BorderBrush}"  

 18                                 BorderThickness="{TemplateBinding BorderThickness}" 

 19                                 SnapsToDevicePixels="True" CornerRadius="5">

 20                             <Border.Background>

 21                                 <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 22                                     <GradientStop Color="Blue" Offset="0"></GradientStop>

 23                                     <GradientStop Color="LightBlue" Offset="0.4"></GradientStop>

 24                                     <GradientStop Color="White" Offset="1"></GradientStop>

 25                                 </LinearGradientBrush>

 26                             </Border.Background>

 27                             <ContentPresenter></ContentPresenter>

 28                         </Border>

 29                     </Grid>

 30                 </ControlTemplate>

 31             </Setter.Value>

 32         </Setter>

 33     </Style>

 34     

 35     <!--Button样式-->

 36     <Style TargetType="Button">

 37         <Setter Property="Width" Value="70"></Setter>

 38         <Setter Property="Height" Value="23"></Setter>

 39         <Setter Property="Template">

 40             <Setter.Value>

 41                 <ControlTemplate TargetType="Button">

 42                     <Border Name="bdr" CornerRadius="5" Cursor="Hand"

 43                             BorderBrush="{TemplateBinding BorderBrush}"  

 44                             BorderThickness="{TemplateBinding BorderThickness}">

 45                         <TextBlock Name="tbk" Background="Transparent" Foreground="Yellow"  TextAlignment="Center"

 46                                    Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"></TextBlock>

 47                         <Border.Background>

 48                             <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 49                                 <GradientStop Color="White" Offset="0"></GradientStop>

 50                                 <GradientStop Color="LightBlue" Offset="0.3"></GradientStop>

 51                                 <GradientStop Color="Blue" Offset="1"></GradientStop>

 52                             </LinearGradientBrush>

 53                         </Border.Background>

 54                     </Border>

 55                     <ControlTemplate.Triggers>

 56                         <Trigger Property="IsMouseOver" Value="True">

 57                             <Setter TargetName="bdr" Property="Background">

 58                                 <Setter.Value>

 59                                     <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 60                                         <GradientStop Color="LightBlue" Offset="0"></GradientStop>

 61                                         <GradientStop Color="Blue" Offset="1"></GradientStop>

 62                                     </LinearGradientBrush>

 63                                 </Setter.Value>

 64                             </Setter>

 65                             <Setter TargetName="tbk" Property="Foreground" Value="LightYellow"></Setter>

 66                         </Trigger>

 67                     </ControlTemplate.Triggers>

 68                 </ControlTemplate>

 69             </Setter.Value>

 70         </Setter>

 71     </Style>

 72 

 73     <!--TextBox样式-->

 74     <Style TargetType="TextBox">

 75         <Setter Property="FontFamily" Value="Times New Roman"></Setter>

 76         <Setter Property="FontSize" Value="14"></Setter>

 77         <Setter Property="Template">

 78             <Setter.Value>

 79                 <ControlTemplate TargetType="TextBox">

 80                     <Border BorderBrush="Blue" BorderThickness="0.5" CornerRadius="5">

 81                         <ScrollViewer x:Name="PART_ContentHost" Focusable="false" 

 82                                       HorizontalScrollBarVisibility="Hidden" 

 83                                       VerticalScrollBarVisibility="Hidden"></ScrollViewer>

 84                     </Border>

 85                 </ControlTemplate>

 86             </Setter.Value>

 87         </Setter>

 88     </Style>

 89 

 90     <!--ContextMenu样式-->

 91     <Style TargetType="ContextMenu">

 92         <Setter Property="Template">

 93             <Setter.Value>

 94                 <ControlTemplate TargetType="ContextMenu">

 95                     <Border CornerRadius="5" BorderBrush="Blue" BorderThickness="1">

 96                         <ItemsPresenter/>

 97                     </Border>

 98                 </ControlTemplate>

 99             </Setter.Value>

100         </Setter>

101     </Style>

102 

103     <!--MenuItem样式-->

104     <Style TargetType="MenuItem">

105         <Setter Property="Template">

106             <Setter.Value>

107                 <ControlTemplate TargetType="MenuItem">

108                     <Border Name="border" Background="LightSkyBlue" BorderThickness="0" CornerRadius="5">

109                         <TextBlock Name="tbk" Background="Transparent" Padding="5,5"

110                                    Text="{TemplateBinding Header}"></TextBlock>

111                     </Border>

112                     <ControlTemplate.Triggers>

113                         <Trigger Property="IsMouseOver" Value="True">

114                             <Setter TargetName="border" Property="Background" Value="BlueViolet"></Setter>

115                             <Setter TargetName="tbk" Property="Foreground" Value="White"></Setter>

116                         </Trigger>

117                     </ControlTemplate.Triggers>

118                 </ControlTemplate>

119             </Setter.Value>

120         </Setter>

121     </Style>

122     

123     <!--TextBlock样式-->

124     <Style TargetType="TextBlock">

125         <Setter Property="FontFamily" Value="Times New Roman"/>

126         <Setter Property="FontSize" Value="14"/>

127     </Style>

128 </ResourceDictionary>
View Code

  仔细观察上面定义的样式,你会发现在定义Window样式的时候指定了Key,其他的Control样式却没有指定Key。大家都知道,如果没有给Style指定Key,那么这个Style会应用到所有目标类型(TargetType)为指定类型的Control。请看下面一段文字:

WPF之换肤

因为在换肤的过程中,需要动态加载Window的样式,所以用DynamicResource作绑定Style="{DynamicResource WindowStyle}"。

App.xaml

程序运行的时候,默认加载规则样式的皮肤。

1     <Application.Resources>

2         <ResourceDictionary>

3             <ResourceDictionary.MergedDictionaries>

4                 <ResourceDictionary Source="Dictionary\Skin.RegularStyle.xaml"></ResourceDictionary>

5             </ResourceDictionary.MergedDictionaries>

6         </ResourceDictionary>

7     </Application.Resources>
View Code

后台代码

 1         /// <summary>

 2         /// MenuItem的执行方法

 3         /// </summary>

 4         /// <param name="parameter"></param>

 5         private void RelayMenuItemEvent(object parameter)

 6         {

 7             if (parameter.ToString() == RegularStyle)

 8             {

 9                 ChangeSkinResource(Skins[0]);

10             }

11             else if (parameter.ToString() == RoundedCornerStyle)

12             {

13                 ChangeSkinResource(Skins[1]);

14             }

15         }

16 

17         /// <summary>

18         /// 更换皮肤资源

19         /// </summary>

20         /// <param name="skin"></param>

21         private void ChangeSkinResource(ResourceDictionary skin)

22         {

23             if (Application.Current.Resources.MergedDictionaries[0].Source.IsAbsoluteUri)

24             {

25                 if (Application.Current.Resources.MergedDictionaries[0].Source.OriginalString != skin.Source.OriginalString)

26                 {

27                     Application.Current.Resources.MergedDictionaries[0] = skin;

28                 }

29             }

30             else

31             {

32                 if (Application.Current.Resources.MergedDictionaries[0].Source.OriginalString.ToString('\\') != skin.Source.OriginalString.ToString('/'))

33                 {

34                     Application.Current.Resources.MergedDictionaries[0] = skin;

35                 }

36             }

37         }
View Code

运行的时候在MainWindow上右键选择皮肤样式,就可以换肤了。

源码下载

链接

stackoverflow

你可能感兴趣的:(WPF)