2019独角兽企业重金招聘Python工程师标准>>>

接上一篇的通用窗体模板,这个模板是重写窗体样式的自定义模板,与上篇不同的是它将窗体的一些基本功能全部清空(放大、缩小、关闭按钮,窗体双击放大缩小,窗体可拖拉大小,标题和logo等)。我们需要重写函数来实现这些功能。

首先是新建窗体文件window.xaml,为何不用资源字典文件呢?因为我们需要写函数所以需要cs文件,而窗体文件新建后会自动生成window.xaml.cs,只需将window标签修改为ResourceDictionary即可。

cs文件中修改:

然后开始写窗体样式,在xaml中添加:

<!-- 菜单按钮组模板 --><Style x:Key="WindowCenterMenuBtn" TargetType="Button"><Setter Property="Foreground" Value="White"></Setter><Setter Property="Opacity" Value="0.2"></Setter><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><TextBlock FontSize="25" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Opacity" Value="1.0"></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style><!-- 通用窗口模板-标题居中 --><ControlTemplate x:Key="WindowCenterTemplate" TargetType="Window"><Border x:Name="WindowCenterFrame" Margin="0" CornerRadius="0" BorderThickness="1" BorderBrush="DodgerBlue"  Background="#FFFFFF" MouseLeftButtonDown="CustomWindow_MouseLeftButtonDown" ><Border.Effect><DropShadowEffect BlurRadius="3" RenderingBias="Performance" ShadowDepth="0" Opacity="1"/></Border.Effect><Grid ><Grid.RowDefinitions><RowDefinition Height="30"></RowDefinition><RowDefinition Height="*"></RowDefinition></Grid.RowDefinitions><Border Grid.Row="0"><Border.Background><LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="0.6"><GradientStop Color="#FFFBFBFC" Offset="1"/><GradientStop Color="#FFF3F7FB" Offset="0.021"/></LinearGradientBrush></Border.Background><Grid MouseDown="CustomWindow_MouseDoubleDown"><Grid.ColumnDefinitions><ColumnDefinition Width="1*"/><ColumnDefinition Width="120"/></Grid.ColumnDefinitions><StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="60,0,0,0"><Button   Width="22"  HorizontalAlignment="Center" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"WindowChrome.IsHitTestVisibleInChrome="True"  Command="{x:Static SystemCommands.ShowSystemMenuCommand}"CommandParameter="{Binding ElementName=_MainWindow}"><!-- Make sure there is a resource with name Icon in MainWindow --><Image  Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}"WindowChrome.IsHitTestVisibleInChrome="True"/></Button><TextBlock   VerticalAlignment="Center" Text="{Binding Title, RelativeSource={RelativeSource TemplatedParent}}"  FontSize="13"/></StackPanel><StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,20,0" VerticalAlignment="Center"><Button x:Name="MinBtn" Height="20" Width="30" Content="-" Style="{StaticResource ResourceKey=WindowCenterMenuBtn}" Click="CustomWindowBtnMinimized_Click" /><Button x:Name="MaxBtn" Height="20" Width="30" Content="□" Style="{StaticResource ResourceKey=WindowCenterMenuBtn}" Click="CustomWindowBtnMaxNormal_Click" /><Button x:Name="CloseBtn" Height="20" Width="30" Content="×" Style="{StaticResource ResourceKey=WindowCenterMenuBtn}" Click="CustomWindowBtnClose_Click" /></StackPanel></Grid></Border><Grid Grid.Row="1"><AdornerDecorator><ContentPresenter></ContentPresenter></AdornerDecorator></Grid></Grid></Border></ControlTemplate><!-- 通用窗口样式-标题居中 --><Style x:Key="WindowCenterChrome" TargetType="Window"><Setter Property="AllowsTransparency" Value="True"></Setter><Setter Property="Background" Value="Transparent"></Setter><Setter Property="WindowStyle" Value="None"></Setter><Setter Property="ResizeMode" Value="NoResize"></Setter><Setter Property="Template" Value="{StaticResource WindowCenterTemplate}"></Setter></Style>

接下来是功能函数,在cs文件中添加代码,实现窗口的放大、缩小、关闭、双击放大缩小、鼠标拖动窗口等。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;namespace Resource.Styles.Base
{public partial class CustomWindow : ResourceDictionary{public class Tools{//双击事件定时器private static DispatcherTimer _timer;//是否单击过一次private static bool _isFirst;static Tools(){_timer = new DispatcherTimer();_timer.Interval = new TimeSpan(0, 0, 0, 0, 400);_timer.Tick += new EventHandler(_timer_Tick);}/// <summary>/// 判断是否双击/// </summary>/// <returns></returns>public static bool IsDoubleClick(){if (!_isFirst){_isFirst = true;_timer.Start();return false;}else{return true;}}//间隔时间private static void _timer_Tick(object sender, EventArgs e){_isFirst = false;_timer.Stop();}}// 拖动private void CustomWindow_MouseLeftButtonDown(object sender, MouseEventArgs e){Window win = (Window) ((FrameworkElement) sender).TemplatedParent;if (e.LeftButton == MouseButtonState.Pressed){win.DragMove();}}//双击放大缩小private void CustomWindow_MouseDoubleDown(object sender, MouseEventArgs e){Window win = (Window) ((FrameworkElement) sender).TemplatedParent;if (Tools.IsDoubleClick()){win.WindowState = win.WindowState == WindowState.Maximized? WindowState.Normal: WindowState.Maximized;}}// 关闭private void CustomWindowBtnClose_Click(object sender, RoutedEventArgs e){Window win = (Window) ((FrameworkElement) sender).TemplatedParent;//提示是否要关闭if (MessageBox.Show("确定要退出系统?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question) ==MessageBoxResult.Yes){System.Windows.Application.Current.Shutdown();}}// 最小化private void CustomWindowBtnMinimized_Click(object sender, RoutedEventArgs e){Window win = (Window) ((FrameworkElement) sender).TemplatedParent;win.WindowState = WindowState.Minimized;}// 最大化、还原private void CustomWindowBtnMaxNormal_Click(object sender, RoutedEventArgs e){Window win = (Window) ((FrameworkElement) sender).TemplatedParent;if (win.WindowState == WindowState.Maximized){win.WindowState = WindowState.Normal;}else{// 不覆盖任务栏win.MaxWidth = SystemParameters.WorkArea.Width;win.MaxHeight = SystemParameters.WorkArea.Height;win.WindowState = WindowState.Maximized;}}}
}

最后在你要应用自定义样式的window窗体中添加引用:

<Window x:Class="EGIS.Main.UI.OPWindow"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"Style="{DynamicResource WindowCenterChrome}" mc:Ignorable="d" WindowStartupLocation="CenterScreen"Loaded="OPWindow_Loaded" ><Window.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/EGIS.Resource;component/Resource/Generic.xaml" /></ResourceDictionary.MergedDictionaries></ResourceDictionary></Window.Resources>

在这个窗体的cs文件中的OPWindow_Loaded函数中添加如下语句(实现页面加载全屏不遮挡任务栏):

 private void OPWindow_Loaded(object sender, RoutedEventArgs e){try{//使页面全屏化但不遮挡任务栏this.MaxWidth = SystemParameters.WorkArea.Width;this.MaxHeight = SystemParameters.WorkArea.Height;this.WindowState = WindowState.Maximized;}catch (Exception ex){LogService.WriteExceptionLog(ex, "");}}

还有一个窗体事件为鼠标拖动改变窗口大小,这个查询了网上的一些方法,最终用下面的代码实现:

 #region 重写页面,鼠标左键拖动改变窗口大小#region 这一部分是四个边加上四个角public enum ResizeDirection{Left = 1,Right = 2,Top = 3,TopLeft = 4,TopRight = 5,Bottom = 6,BottomLeft = 7,BottomRight = 8,}#endregion#region 用于改变窗体大小[DllImport("user32.dll", CharSet = CharSet.Auto)]private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);private void ResizeWindow(ResizeDirection direction){SendMessage(hs.Handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);}#endregion#region 为元素注册事件private void InitializeEvent(){//获取当前窗口调用的style样式Style temStyle = this.Resources["CustomWindowChrome"] as Style;if (temStyle!=null){Setter temSetter = null;foreach (Setter item in temStyle.Setters){if (item.Value == Template)temSetter = item;}ControlTemplate baseWindowTemplate = (ControlTemplate)temSetter.Value;Border borderClip = (Border)baseWindowTemplate.FindName("CustomWindowFrame", this);borderClip.MouseMove += delegate{DisplayResizeCursor(null, null);};borderClip.PreviewMouseDown += delegate{Resize(null, null);};borderClip.MouseLeftButtonDown += delegate{DragMove();};this.PreviewMouseMove += delegate{ResetCursor(null, null);};}}#endregion#region 重写的DragMove,以便解决利用系统自带的DragMove出现Exception的情况public new void DragMove(){if (this.WindowState == WindowState.Normal){SendMessage(hs.Handle, WM_SYSCOMMAND, (IntPtr)0xf012, IntPtr.Zero);SendMessage(hs.Handle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);}}#endregion#region 显示拖拉鼠标形状private void DisplayResizeCursor(object sender, MouseEventArgs e){Point pos = Mouse.GetPosition(this);double x = pos.X;double y = pos.Y;double w = this.ActualWidth;  //注意这个地方使用ActualWidth,才能够实时显示宽度变化double h = this.ActualHeight;if (x <= relativeClip & y <= relativeClip) // left top{this.Cursor = Cursors.SizeNWSE;}if (x >= w - relativeClip & y <= relativeClip) //right top{this.Cursor = Cursors.SizeNESW;}if (x >= w - relativeClip & y >= h - relativeClip) //bottom right{this.Cursor = Cursors.SizeNWSE;}if (x <= relativeClip & y >= h - relativeClip)  // bottom left{this.Cursor = Cursors.SizeNESW;}if ((x >= relativeClip & x <= w - relativeClip) & y <= relativeClip) //top{this.Cursor = Cursors.SizeNS;}if (x >= w - relativeClip & (y >= relativeClip & y <= h - relativeClip)) //right{this.Cursor = Cursors.SizeWE;}if ((x >= relativeClip & x <= w - relativeClip) & y > h - relativeClip) //bottom{this.Cursor = Cursors.SizeNS;}if (x <= relativeClip & (y <= h - relativeClip & y >= relativeClip)) //left{this.Cursor = Cursors.SizeWE;}}#endregion#region  还原鼠标形状private void ResetCursor(object sender, MouseEventArgs e){if (Mouse.LeftButton != MouseButtonState.Pressed){this.Cursor = Cursors.Arrow;}}#endregion#region 判断区域,改变窗体大小private void Resize(object sender, MouseButtonEventArgs e){Point pos = Mouse.GetPosition(this);double x = pos.X;double y = pos.Y;double w = this.ActualWidth;double h = this.ActualHeight;if (x <= relativeClip & y <= relativeClip) // left top{this.Cursor = Cursors.SizeNWSE;ResizeWindow(ResizeDirection.TopLeft);}if (x >= w - relativeClip & y <= relativeClip) //right top{this.Cursor = Cursors.SizeNESW;ResizeWindow(ResizeDirection.TopRight);}if (x >= w - relativeClip & y >= h - relativeClip) //bottom right{this.Cursor = Cursors.SizeNWSE;ResizeWindow(ResizeDirection.BottomRight);}if (x <= relativeClip & y >= h - relativeClip)  // bottom left{this.Cursor = Cursors.SizeNESW;ResizeWindow(ResizeDirection.BottomLeft);}if ((x >= relativeClip & x <= w - relativeClip) & y <= relativeClip) //top{this.Cursor = Cursors.SizeNS;ResizeWindow(ResizeDirection.Top);}if (x >= w - relativeClip & (y >= relativeClip & y <= h - relativeClip)) //right{this.Cursor = Cursors.SizeWE;ResizeWindow(ResizeDirection.Right);}if ((x >= relativeClip & x <= w - relativeClip) & y > h - relativeClip) //bottom{this.Cursor = Cursors.SizeNS;ResizeWindow(ResizeDirection.Bottom);}if (x <= relativeClip & (y <= h - relativeClip & y >= relativeClip)) //left{this.Cursor = Cursors.SizeWE;ResizeWindow(ResizeDirection.Left);}}#endregion#endregion

代码中注意修改一下,将CustomWindowChrome改为通用窗体的名称WindowCenterChrome。CustomWindowFrame修改为WindowCenterFrame。

到此,一个完全重写的自定义样式就完成了,还有一点和上篇的通用窗体样式一样,会与WindowsFormsHost控件有冲突。

注意代码中的标签或样式名称问题,可能会有没有统一的部分,使用时自己排查一下。

转载于:https://my.oschina.net/u/3661223/blog/1540704

WPF通用窗体模板【2】相关推荐

  1. .NET CORE(C#) WPF亚克力窗体

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF亚克力窗体 阅读导航 本文背景 代码实现 本文参考 源码 1 ...

  2. WPF自定义窗体仿新毒霸关闭特效(只能在自定义窗体中正常使用)

    比较简单的一个小功能,和新毒霸类似的效果. 效果代码: bool closeStoryBoardCompleted = false;DoubleAnimation closeAnimation1;vo ...

  3. 《深入浅出WPF》笔记——模板篇

    原文:<深入浅出WPF>笔记--模板篇 我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法 ...

  4. [转][小结][三种方法]实现WPF不规则窗体

    实现WPF不规则窗体的三种常用的方法如下: 1.使用Blend等工具绘制一个不规则xaml,然后作为窗体的背景.这个可以参考xiaowei0705的这篇博文:WPF制作不规则的窗体 . 2.给wind ...

  5. 工作日报模板_千份财会人通用工作模板:自动核算工资、财务分析报表等等

    财务人的日常工作中,最不可或缺的就是各种表格,比如:工资表.成本核算表以及各种财务分析报表,总是会感到无从下手.而且,就财务分析报表而言,即是公司年度会议上需要重量级展示的,更是BOSS最为关心的存在 ...

  6. python可视化界面编程 pycharm_pycharm开发一个简单界面和通用mvc模板(操作方法图解)...

    文章首先使用pycharm的 PyQt5 Designer 做一个简单的界面,然后引入所谓的"mvc框架". 一.设计登录界面 下面开始第一个话题,使用pycharm的 PyQt5 ...

  7. 你知道WPF这三大模板实例运用吗?

    1.介绍 对于Windows桌面端应用开发来讲,WPF以其界面渲染的特殊性,灵活的界面布局而让人津津乐道,因为它能为用户提供更好的交互体验.如何利用WPF开发出让人赏心悦目的界面与功能呢?这里不仅仅只 ...

  8. winform窗体模板_如何验证角模板驱动的窗体

    winform窗体模板 介绍 (Introduction) In this article, we will learn about validations in Angular template-d ...

  9. 通用Makefile模板

    #################################################################################################### ...

最新文章

  1. linux smb配置目录,linux基础---smb配置
  2. pandas 官方API
  3. 在Vivado中,使用锁定增量编译技术进行增量综合布局布线
  4. Windows Phone 7 自适应键盘输入
  5. Activiti6 use spring-boot-starter-web meet requestMappingHandlerMapping error
  6. Docker上部署FTP服务器(基于stilliard/pure-ftpd)
  7. 联想 键盘 fn linux,开发者提交补丁,Linux 5.10 或支持联想 PC 键盘快捷键
  8. 高质量C /C编程指南---第1章 文件机关
  9. 计算机毕业设计中用Java 实现系统权限控制
  10. Emgu.CV.CvInvoke的类型初始值设定项引发异常
  11. spring整合cxf开发rest风格的webservice接口(客户端服务端)
  12. tomcat-内存溢出java.lang.OutOfMemoryErrory:PermGen space解决方法
  13. 计算机组成原理完整学习笔记(三):存储器
  14. mocano editor中使用代码比对功能
  15. 【编译原理系列】语法分析与上下文无关文法
  16. 为什么经转速环PI之后的输出量是电流(基于MTPA分析,内含代码)
  17. kaggle入门titanic分析
  18. unity利用帧动画制作特效
  19. 注册微信小程序的操作步骤
  20. 【Pyecharts50例】自定义饼图标签/显示百分比

热门文章

  1. 大数据之-Hadoop_大数据技术生态体系---大数据之hadoop工作笔记0014
  2. Vue模板语法---vue工作笔记0003
  3. JAVA线程池_并发队列工作笔记0004---Callable原理_多线程执行Callable任务
  4. Netty工作笔记0036---单Reactor单线程模式
  5. python数据结构剑指offer-两个链表的第一个公共结点
  6. 什么时候会用到拷贝构造函数?
  7. 介绍目前计算机网络的新技术,当前计算机网络技术实验室建设现状及方向
  8. 一步一步写算法(之线性堆栈)
  9. 字符串过滤非数字c语言,【新手】【求思路】如何判断用户输入的字符串中是否含有非数字?...
  10. php跳转到safari打开,新手教程: 如何重新打开关闭的Safari标签