分享一个自己写的WPF换肤窗体WPF.DazzleUI
最近自己在自学WPF,看了网上很多前辈的WPF例子,觉得很炫,自己也有点冲动,就尝试着写了一下。
桌面程序嘛,要炫起来,当然首先得窗体先炫起来,所以就自己写了一个可以换肤的WPF窗体基类。
不多说,先上图:
怎么样,看起来效果还是不错吧。
先发个demo的下载地址: 例子下载 http://pan.baidu.com/share/link?shareid=565013&uk=1108265080
其实,已开始看别人的东西,觉得很神奇,不过自己写下来,觉得也没那么复杂。只不过由于,WPF引入了XAML,跟以前winform时代有很大差别,需要一个转换过程。多写写代码就好了。
View Code
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:DazzleWPF="clr-namespace:WPF.DazzleUI.Controls"
xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
xmlns:converters="clr-namespace:WPF.DazzleUI.Converters">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WPF.DazzleUI;component/Assets/ImageButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ResizeModeToVisibilityConverter x:Key="ResizeModeToVisibilityConverter" />
<Style TargetType="DazzleWPF:DazzleWindow">
<Setter Property="Width" Value="800" />
<Setter Property="Height" Value="640" />
<Setter Property="MinWidth" Value="50" />
<Setter Property="MinHeight" Value="50" />
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DazzleWPF:DazzleWindow">
<Grid Background="#ffffff">
<Border BorderBrush="#3399ff" BorderThickness="0">
<AdornerDecorator>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="*" />
<RowDefinition Height="15" />
</Grid.RowDefinitions>
<!-- header background -->
<Rectangle x:Name="HeaderBackground" Grid.RowSpan="5" Height="196"
VerticalAlignment="Top"
Visibility="{DynamicResource Color_ImageOrColor}">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0, 0" EndPoint="0, 1" Opacity=".1">
<GradientStop Offset="0" Color="{DynamicResource DazzleUI_BackGroudColor}" />
<GradientStop Offset=".3" Color="{DynamicResource DazzleUI_BackGroudColor}" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Image Source="{DynamicResource DazzleUI_BackGroudImage}" Grid.RowSpan="5" Stretch="UniformToFill" VerticalAlignment="Top"
Visibility="{DynamicResource Image_ImageOrColor}">
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#FF000000" Offset="0"></GradientStop>
<GradientStop Color="#33000000" Offset="0.5"></GradientStop>
<GradientStop Color="#00000000" Offset="1"></GradientStop>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
<ContentPresenter Grid.Row="1" Grid.RowSpan="2"></ContentPresenter>
<!-- window system buttons-->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0" shell:WindowChrome.IsHitTestVisibleInChrome="True" Height="20">
<DazzleWPF:ImageButton Width="28" Height="20"
Visibility="{Binding ResizeMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource ResizeModeToVisibilityConverter}, ConverterParameter=MinButton}"
Command="{Binding Source={x:Static shell:SystemCommands.MinimizeWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_mini_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_mini_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_mini_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_mini_normal.png"></DazzleWPF:ImageButton>
<DazzleWPF:ImageButton x:Name="MaxButton" Width="28" Height="20"
Visibility="{Binding ResizeMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource ResizeModeToVisibilityConverter}, ConverterParameter=MaxButton}"
Command="{Binding Source={x:Static shell:SystemCommands.MaximizeWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_max_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_max_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_max_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_max_normal.png"></DazzleWPF:ImageButton>
<DazzleWPF:ImageButton x:Name="RestoreButton" Width="28" Height="20" Visibility="Collapsed"
Command="{Binding Source={x:Static shell:SystemCommands.RestoreWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_restore_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_restore_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_restore_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_restore_normal.png"></DazzleWPF:ImageButton>
<DazzleWPF:ImageButton Width="39" Height="20" ImageSize="39"
Command="{Binding Source={x:Static shell:SystemCommands.CloseWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_close_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_close_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_close_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_close_normal.png"></DazzleWPF:ImageButton>
</StackPanel>
<!-- resize grip -->
<Grid Grid.Row="2" >
<Path x:Name="ResizeGrip" Visibility="Collapsed" Width="12" Height="12" Margin="1" HorizontalAlignment="Right"
Stroke="#333333"
StrokeThickness="1"
Stretch="None"
Data="F1 M1,10 L3,10 M5,10 L7,10 M9,10 L11,10 M2,9 L2,11 M6,9 L6,11 M10,9 L10,11 M5,6 L7,6 M9,6 L11,6 M6,5 L6,7 M10,5 L10,7 M9,2 L11,2 M10,1 L10,3" />
</Grid>
</Grid>
</AdornerDecorator>
</Border>
<Border BorderBrush="#7fbfff" BorderThickness="1"
Visibility="{Binding !IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Border BorderBrush="#3399ff" BorderThickness="1"
Visibility="{Binding IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource BooleanToVisibilityConverter}}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
</Trigger>
<Trigger Property="DazzleWindowState" Value="Maximized">
<Setter TargetName="MaxButton" Property="Visibility" Value="Collapsed" />
<Setter TargetName="RestoreButton" Property="Visibility" Value="Visible" />
<Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
</Trigger>
<Trigger Property="DazzleWindowState" Value="Normal">
<Setter TargetName="MaxButton" Property="Visibility" Value="Visible" />
<Setter TargetName="RestoreButton" Property="Visibility" Value="Collapsed" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="CanResizeWithGrip" />
<Condition Property="WindowState" Value="Normal" />
</MultiTrigger.Conditions>
<Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:DazzleWPF="clr-namespace:WPF.DazzleUI.Controls"
xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
xmlns:converters="clr-namespace:WPF.DazzleUI.Converters">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WPF.DazzleUI;component/Assets/ImageButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ResizeModeToVisibilityConverter x:Key="ResizeModeToVisibilityConverter" />
<Style TargetType="DazzleWPF:DazzleWindow">
<Setter Property="Width" Value="800" />
<Setter Property="Height" Value="640" />
<Setter Property="MinWidth" Value="50" />
<Setter Property="MinHeight" Value="50" />
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DazzleWPF:DazzleWindow">
<Grid Background="#ffffff">
<Border BorderBrush="#3399ff" BorderThickness="0">
<AdornerDecorator>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="*" />
<RowDefinition Height="15" />
</Grid.RowDefinitions>
<!-- header background -->
<Rectangle x:Name="HeaderBackground" Grid.RowSpan="5" Height="196"
VerticalAlignment="Top"
Visibility="{DynamicResource Color_ImageOrColor}">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0, 0" EndPoint="0, 1" Opacity=".1">
<GradientStop Offset="0" Color="{DynamicResource DazzleUI_BackGroudColor}" />
<GradientStop Offset=".3" Color="{DynamicResource DazzleUI_BackGroudColor}" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Image Source="{DynamicResource DazzleUI_BackGroudImage}" Grid.RowSpan="5" Stretch="UniformToFill" VerticalAlignment="Top"
Visibility="{DynamicResource Image_ImageOrColor}">
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#FF000000" Offset="0"></GradientStop>
<GradientStop Color="#33000000" Offset="0.5"></GradientStop>
<GradientStop Color="#00000000" Offset="1"></GradientStop>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
<ContentPresenter Grid.Row="1" Grid.RowSpan="2"></ContentPresenter>
<!-- window system buttons-->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0" shell:WindowChrome.IsHitTestVisibleInChrome="True" Height="20">
<DazzleWPF:ImageButton Width="28" Height="20"
Visibility="{Binding ResizeMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource ResizeModeToVisibilityConverter}, ConverterParameter=MinButton}"
Command="{Binding Source={x:Static shell:SystemCommands.MinimizeWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_mini_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_mini_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_mini_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_mini_normal.png"></DazzleWPF:ImageButton>
<DazzleWPF:ImageButton x:Name="MaxButton" Width="28" Height="20"
Visibility="{Binding ResizeMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource ResizeModeToVisibilityConverter}, ConverterParameter=MaxButton}"
Command="{Binding Source={x:Static shell:SystemCommands.MaximizeWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_max_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_max_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_max_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_max_normal.png"></DazzleWPF:ImageButton>
<DazzleWPF:ImageButton x:Name="RestoreButton" Width="28" Height="20" Visibility="Collapsed"
Command="{Binding Source={x:Static shell:SystemCommands.RestoreWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_restore_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_restore_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_restore_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_restore_normal.png"></DazzleWPF:ImageButton>
<DazzleWPF:ImageButton Width="39" Height="20" ImageSize="39"
Command="{Binding Source={x:Static shell:SystemCommands.CloseWindowCommand}}"
NormalImage="/WPF.DazzleUI;component/Resources/btn_close_normal.png"
HoverImage="/WPF.DazzleUI;component/Resources/btn_close_highlight.png"
PressedImage="/WPF.DazzleUI;component/Resources/btn_close_down.png"
DisabledImage="/WPF.DazzleUI;component/Resources/btn_close_normal.png"></DazzleWPF:ImageButton>
</StackPanel>
<!-- resize grip -->
<Grid Grid.Row="2" >
<Path x:Name="ResizeGrip" Visibility="Collapsed" Width="12" Height="12" Margin="1" HorizontalAlignment="Right"
Stroke="#333333"
StrokeThickness="1"
Stretch="None"
Data="F1 M1,10 L3,10 M5,10 L7,10 M9,10 L11,10 M2,9 L2,11 M6,9 L6,11 M10,9 L10,11 M5,6 L7,6 M9,6 L11,6 M6,5 L6,7 M10,5 L10,7 M9,2 L11,2 M10,1 L10,3" />
</Grid>
</Grid>
</AdornerDecorator>
</Border>
<Border BorderBrush="#7fbfff" BorderThickness="1"
Visibility="{Binding !IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Border BorderBrush="#3399ff" BorderThickness="1"
Visibility="{Binding IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource BooleanToVisibilityConverter}}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
</Trigger>
<Trigger Property="DazzleWindowState" Value="Maximized">
<Setter TargetName="MaxButton" Property="Visibility" Value="Collapsed" />
<Setter TargetName="RestoreButton" Property="Visibility" Value="Visible" />
<Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
</Trigger>
<Trigger Property="DazzleWindowState" Value="Normal">
<Setter TargetName="MaxButton" Property="Visibility" Value="Visible" />
<Setter TargetName="RestoreButton" Property="Visibility" Value="Collapsed" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ResizeMode" Value="CanResizeWithGrip" />
<Condition Property="WindowState" Value="Normal" />
</MultiTrigger.Conditions>
<Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
终于把代码贴上来了,不知道啥问题
源码只贴出来了主窗体的,全部贴出来代码太多了,估计也不容易看懂,拷贝过去也不一定能运行。大家有想要源码,留个邮箱吧,我发给大家。
PS:给大家介绍一些文章、开源的框架,我的程序也是参考这么前辈的写出来的。
Modern UI for WPF https://mui.codeplex.com/
这个可是个好东西,我的代码基本是参考它来的。
mahapps.metro http://mahapps.com/mahapps.metro/
这个的效果也很不错。WPF - Image Button https://imagebuttonwpf.codeplex.com/
这个很实用哦
WPF换肤系列文章