如何实现一个窗口的风格(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 >= )
{
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的窗口,都有统一的风格了!

当然,如上的窗口还不是那么漂亮完美,但是相信你有办法把它做的美美的!

WPF窗口继承实现统一风格的自定义窗口的更多相关文章

  1. WPF 实现完全可控制的漂亮自定义窗口

    在WPF界面开发中,有时候不想用系统的死板的窗口,想要来点新花样,常会自定义窗口. 那么,先抛出问题,想搞出下面这样的窗口,该咋整 ? aa  下面看一个啥也没设置过的普通窗口,这样的窗口,我们只能控 ...

  2. WPF.UIShell UIFramework之自定义窗口的深度技术 - 模态闪动(Blink)、窗口四边拖拽支持(WmNCHitTest)、自定义最大化位置和大小(WmGetMinMaxInfo)

    无论是在工作和学习中使用WPF时,我们通常都会接触到CustomControl,今天我们就CustomWindow之后的一些边角技术进行探讨和剖析. 窗口(对话框)模态闪动(Blink) 自定义窗口的 ...

  3. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):1. 自定义窗口部件 (widget)

    1. 框架代码 用 PyCharm 新建一个名为 SimplePaintApp 的项目,然后新建一个名为 simple_paint_app.py 的 Python 源文件, 在代码编辑器中,输入以下框 ...

  4. unity编辑器扩展_08(创建自定义窗口)

    代码: using UnityEngine;using UnityEditor; public class MyWidow : EditorWindow{    [MenuItem("Win ...

  5. [WPF疑难] 继承自定义窗口

    原文 [WPF疑难] 继承自定义窗口 [WPF疑难] 继承自定义窗口 周银辉 项目中有不少的弹出窗口,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于Window自身的,但每个弹出框 ...

  6. WPF 之 创建继承自Window 基类的自定义窗口基类

    开发项目时,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于 Window 自身的,但窗口的外边框及窗口移动.最小化等标题栏操作基本都是一样的.所以通过查看资料,可按如下方法创建继承 ...

  7. WPF自定义窗口基类

    WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...

  8. WPF自学入门(九)WPF自定义窗口基类

    今天简单记录一个知识点:WPF自定义窗口基类,常用winform的人知道,winform的窗体继承是很好用的,写一个基础窗体,直接在后台代码改写继承窗体名.但如果是WPF要继承窗体,我个人感觉没有理解 ...

  9. WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)

    WPF 自定义窗口样式有多种方式,不过基本核心实现都是在修改 Win32 窗口样式.然而,Windows 上的应用就应该有 Windows 应用的样子嘛,在保证自定义的同时也能与其他窗口样式保持一致当 ...

随机推荐

  1. 嵌入式Qt-4.8.6显示中文并且改变字体大小和应用自己制作的字体库

    问题: QT4.8.6在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器中的字号与开发板中的字号一致. 详解: 1>如何让QT支 ...

  2. Oracle 12CR2 中alert.log出现大量的 WARNING: too many parse errors 告警

    Oracle 12CR2 中alert.log出现大量的 WARNING: too many parse errors 告警   日志如下: 2018-06-24T17:16:21.024586+08 ...

  3. POJ 1595 Prime Cuts (ZOJ 1312) 素数打表

    ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=312 POJ:http://poj.org/problem?id=159 ...

  4. The behavior of App killed or restored by Android System or by users

    What's the behavior of App killed or restored by Android System or by users? First, user kills the a ...

  5. percona-toolkit源码编译安装

    安装依赖软件yum install perl-ExtUtils-CBuilder perl-ExtUtils-MakeMakeryum install  perl-Time-HiRes perl-DB ...

  6. UVA 11732 - strcmp() Anyone? 字典树

    传送门:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  7. 【z08】乌龟棋

    描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点 ...

  8. mina架构分析

    使用的版本号是2.0.9 IoService分析 AbstractIoAcceptor定义了全部的public接口,并定义了子类须要实现的bindInternal函数,AbstractPollingI ...

  9. 【u106】3D模型

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一座城市建立在规则的n×m网格上,并且网格均由1×1正方形构成.在每个网格上都可以有一个建筑,建筑由若 ...

  10. 计算git树上随意两点的近期切割点。

    1.git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比方: base'<--base<--A<--A' ^ | --- B<--B' 小米project师 ...