如何实现一个窗口的风格(style),让所有的窗口都继承这样同样的风格,包括标题栏,放大、缩小和关闭按钮。
那么,我们可不可以就建立一个Base窗口,然后将这个窗口的风格给设计好之后,所有的窗口都继承自他呢?
答案是否定的,我们一定要知道,窗口是一个类,它可以继承,但是风格(XAML)文件是继承不了的。
所以我们能够做到的是:
1、窗口类继承,BaseWindow封装窗口最大化按钮,最小化按钮的点击等事件。
2、风格(Style)就利用属性来设置,把window看成一个控件,利用Style=“BaseWindowStyle”就可以了。
以下是详细的步骤:
1、新建一个BaseWindowStyle的模板文件。点击项目名称,右键“添加”->”资源字典”->输入名称为“BaseWindowStyle.xaml”,然后将以下的末班文件拷贝进去:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ControlTemplate x:Key="WindowTemplateKey" TargetType="{x:Type Window}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Grid> <AdornerDecorator> <ContentPresenter /> </AdornerDecorator> <ResizeGrip Visibility="Collapsed" IsTabStop="false" HorizontalAlignment="Right" x:Name="WindowResizeGrip" VerticalAlignment="Bottom" /> </Grid> </Border> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="ResizeMode" Value="CanResizeWithGrip" /> <Condition Property="WindowState" Value="Normal" /> </MultiTrigger.Conditions> <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible" /> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="BaseWindowControlTemplate" TargetType="{x:Type Window}"> <DockPanel LastChildFill="True"> <!--外边框--> <Border Width="Auto" Height="Auto" DockPanel.Dock="Top" Background="#FF7097D0" CornerRadius="0,0,0,0" x:Name="borderTitle"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"> </ColumnDefinition> <ColumnDefinition Width="*"> </ColumnDefinition> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Margin="20,0,2,2" Name="Title" VerticalAlignment="Top" FontSize="20" Foreground="White" Text="{TemplateBinding Title}"/> <StackPanel Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal"> <!--最小化按钮--> <Button x:Name="btnMin" Content="M" Margin="2,2,2,2" Style="{DynamicResource MinButtonStyle}"/> <!--最大化按钮--> <Button x:Name="btnMax" Content="M" Margin="2,2,2,2" Style="{DynamicResource MaxButtonStyle}"/> <!--关闭按钮--> <Button x:Name="btnClose" Content="M" Margin="2,2,2,2" Style="{DynamicResource CloseButtonStyle}"/> </StackPanel> </Grid> </Border> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="Auto" Height="Auto" DockPanel.Dock="Top" CornerRadius="0,0,4,4"> <AdornerDecorator> <ContentPresenter /> </AdornerDecorator> </Border> </DockPanel> </ControlTemplate> <Style x:Key="BaseWindowStyle" TargetType="{x:Type Window}"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" /> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" /> <Setter Property="Template" Value="{StaticResource BaseWindowControlTemplate}"/> <Setter Property="AllowsTransparency" Value="True" /> <Setter Property="WindowStyle" Value="None" /> <Setter Property="BorderBrush" Value="#FF7097D0" /> <Setter Property="BorderThickness" Value="4,4,4,4" /> <Style.Triggers> <Trigger Property="ResizeMode" Value="CanResizeWithGrip"> <Setter Property="Template" Value="{StaticResource WindowTemplateKey}" /> </Trigger> </Style.Triggers> </Style> <!--最小化按钮--> <Style x:Key="MinButtonStyle" TargetType="{x:Type Button}"> <Setter Property="Foreground" Value="Black"/> <!--修改模板属性--> <Setter Property="Template"> <Setter.Value> <!--控件模板--> <ControlTemplate TargetType="Button"> <!--背景色--> <Border x:Name="back" Opacity="0.8" CornerRadius="0" BorderBrush="#FFCDA05F" Background="#FFFFE9C9" BorderThickness="1" Margin="1" Padding="2,0,0,0"> <!--按钮内容--> <Path x:Name="cp" Width="12" Height="12" Stroke="#FFCEA15F" StrokeThickness="3" Fill="Black"> <Path.Data> <PathGeometry Figures="M 0,6 H 6,6 " /> </Path.Data> </Path> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" TargetName="back" Value="#FFD4BD9B"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" TargetName="back" Value="#FFCDA05F"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--最大化按钮--> <Style x:Key="MaxButtonStyle" TargetType="{x:Type Button}"> <Setter Property="Foreground" Value="Black"/> <!--修改模板属性--> <Setter Property="Template"> <Setter.Value> <!--控件模板--> <ControlTemplate TargetType="Button"> <!--背景色--> <Border x:Name="back" Opacity="0.8" CornerRadius="0" BorderBrush="#FFCDA05F" Background="#FFFFE9C9" BorderThickness="1" Margin="1" Padding="2,0,0,0"> <!--按钮内容--> <Path x:Name="cp" Width="12" Height="12" Stroke="#FFCEA15F" StrokeThickness="3" > <Path.Data> <PathGeometry Figures="M 0,0 L 0,12 12,12 12,0 0,0" /> </Path.Data> </Path> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" TargetName="back" Value="#FFD4BD9B"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" TargetName="back" Value="#FFCDA05F"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--关闭按钮--> <Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}"> <Setter Property="Foreground" Value="Black"/> <!--修改模板属性--> <Setter Property="Template"> <Setter.Value> <!--控件模板--> <ControlTemplate TargetType="Button"> <!--背景色--> <Border x:Name="back" Opacity="0.8" CornerRadius="0" BorderBrush="#FFCDA05F" Background="#FFFFE9C9" BorderThickness="1" Margin="1" Padding="2,0,0,0"> <!--按钮内容--> <Path x:Name="cp" Width="12" Height="12" Stroke="#FFCEA15F" StrokeThickness="3" > <Path.Data> <PathGeometry Figures="M 0,0 L 12,12 M 0,12 L 12,0" /> </Path.Data> </Path> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" TargetName="back" Value="#FFD4BD9B"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" TargetName="back" Value="#FFCDA05F"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
2、引用该模板文件。资源文件建立后,我们需要在程序中引用这个文件,打开APP.XAML,将引用的BaseWindowStyle添加进去:
<Application 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" mc:Ignorable="d" x:Class="MyFirst.App" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary Source="BaseWindowStyle.xaml"> </ResourceDictionary> </Application.Resources> </Application>
3、建立BaseWindow类,实现窗口点击,拖动等事件。在工程上点击右键“添加”->“类”->输入”BaseWindow.cs“
该类继承自Window,然后要载入模板文件,在模板文件中获取最小化、最大化等按钮,然后将这些按钮的点击事件和窗口绑定起来,实现窗口的响应:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace MyFirst { public class BaseWindow : Window { public BaseWindow() { InitializeStyle(); this.Loaded += delegate { InitializeEvent(); }; } private void InitializeEvent() { ControlTemplate baseWindowTemplate = (ControlTemplate)App.Current.Resources["BaseWindowControlTemplate"]; Button minBtn = (Button)baseWindowTemplate.FindName("btnMin", this); minBtn.Click += delegate { this.WindowState = WindowState.Minimized; }; Button maxBtn = (Button)baseWindowTemplate.FindName("btnMax", this); maxBtn.Click += delegate { this.WindowState = (this.WindowState == WindowState.Normal ? WindowState.Maximized : WindowState.Normal); }; Button closeBtn = (Button)baseWindowTemplate.FindName("btnClose", this); closeBtn.Click += delegate { this.Close(); }; Border borderTitle = (Border)baseWindowTemplate.FindName("borderTitle", this); borderTitle.MouseMove += delegate(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { this.DragMove(); } }; borderTitle.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { if (e.ClickCount >= 2) { maxBtn.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); } }; } private void InitializeStyle() { this.Style = (Style)App.Current.Resources["BaseWindowStyle"]; } } }
4,其它窗口类继承自BaseWindow:
public partial class MainWindow : BaseWindow
5,其它窗口的风格指向BaseWindowStyle。
这里要注意一点Winodow的风格可不是直接 Style=”BaseWindowStyle” 那么简单,可以看看MainWindow.xaml的代码:
<local:BaseWindow x:Class="MyFirst.Login" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:src="clr-namespace:MyFirst" Title="MainWindow" Height="300" Width="300"> </local:BaseWindow>
经过这么多步,我们终于实现了凡是继承自BaseWindow的窗口,都有统一的风格了!
当然,如上的窗口还不是那么漂亮完美,但是相信你有办法把它做的美美的!