WPF 基础控件之Window样式

WPF开发者QQ群: 340500857

       由于微信群人数太多入群请添加小编微信号

 yanjinhuawechatW_Feng_aiQ 邀请入群

 需备注WPF开发者 

  PS:有更好的方式欢迎推荐。

01

代码如下

一、创建 Window.cs继承System.Windows.Window代码如下。

      在WPF自定义类库时需要注意在创建自定义Window时 默认新建的资源文件会找不到Style导致Window打开会成为黑色窗体解决方案有两种如下:

1)通过Style的Key去资源字典找到并替换窗体元数据。

static T GetResourceKey<T>(string key){if (Application.Current.TryFindResource(key) is T resource){return resource;}return default;}

2)直接对自定义库下的Themes文件夹下Generic.xaml资源写自定义Window的样式即可。

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;namespace WPFDevelopers.Minimal.Net45x
{public class Window : System.Windows.Window{public double TitleHeight{get { return (double)GetValue(TitleHeightProperty); }set { SetValue(TitleHeightProperty, value); }}public static readonly DependencyProperty TitleHeightProperty =DependencyProperty.Register("TitleHeight", typeof(double), typeof(Window), new PropertyMetadata(50d));static Window(){StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(GetResourceKey<Style>("WPFDevelopersWindow")));}static T GetResourceKey<T>(string key){if (Application.Current.TryFindResource(key) is T resource){return resource;}return default;}public Window(){this.Loaded += Window_Loaded;CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow, CanResizeWindow));CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, RestoreWindow, CanResizeWindow));//CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));}private void Window_Loaded(object sender, RoutedEventArgs e){hWnd = new WindowInteropHelper(this).Handle;HwndSource.FromHwnd(hWnd).AddHook(WindowProc);}protected override void OnContentRendered(EventArgs e){base.OnContentRendered(e);if (SizeToContent == SizeToContent.WidthAndHeight)InvalidateMeasure();}#region Window Commandsprivate void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e){e.CanExecute = ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;}private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e){e.CanExecute = ResizeMode != ResizeMode.NoResize;}private void CloseWindow(object sender, ExecutedRoutedEventArgs e){//Close();SystemCommands.CloseWindow(this);}private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e){SystemCommands.MaximizeWindow(this);}private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e){//SystemCommands.MinimizeWindow(this);SendMessage(hWnd, ApiCodes.WM_SYSCOMMAND, new IntPtr(ApiCodes.SC_MINIMIZE), IntPtr.Zero);}private void RestoreWindow(object sender, ExecutedRoutedEventArgs e){SystemCommands.RestoreWindow(this);}internal class ApiCodes{public const int SC_RESTORE = 0xF120;public const int SC_MINIMIZE = 0xF020;public const int WM_SYSCOMMAND = 0x0112;}private IntPtr hWnd;[DllImport("user32.dll")]public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){if (msg == ApiCodes.WM_SYSCOMMAND){if (wParam.ToInt32() == ApiCodes.SC_MINIMIZE){WindowStyle = WindowStyle.SingleBorderWindow;WindowState = WindowState.Minimized;handled = true;}else if (wParam.ToInt32() == ApiCodes.SC_RESTORE){WindowState = WindowState.Normal;WindowStyle = WindowStyle.None;handled = true;}}return IntPtr.Zero;}private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e){var element = e.OriginalSource as FrameworkElement;if (element == null)return;var point = WindowState == WindowState.Maximized ? new Point(0, element.ActualHeight): new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);point = element.TransformToAncestor(this).Transform(point);SystemCommands.ShowSystemMenu(this, point);}#endregion}
}

二、创建资源字典Window.xaml。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfdev="clr-namespace:WPFDevelopers.Minimal.Net45x" ><Style x:Key="WindowButtonStyle" TargetType="{x:Type Button}"><Setter Property="Foreground" Value="{DynamicResource PrimaryTextSolidColorBrush}"/><Setter Property="Padding" Value="3"/><Setter Property="Margin" Value="0"/><Setter Property="MinWidth" Value="30"/><Setter Property="MinHeight" Value="28"/><Setter Property="BorderThickness" Value="1"/><Setter Property="Cursor" Value="Hand"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Grid Background="Transparent"><VisualStateManager.VisualStateGroups><VisualStateGroup x:Name="CommonStates"><VisualState x:Name="Normal"/><VisualState x:Name="MouseOver"><Storyboard><DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)"Storyboard.TargetName="PART_ContentPresenter" /></Storyboard></VisualState><VisualState x:Name="Pressed"><Storyboard><DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PART_ContentPresenter" /></Storyboard></VisualState><VisualState x:Name="Disabled"><Storyboard><DoubleAnimation Duration="0" To="0.3" Storyboard.TargetProperty="(UIElement.Opacity)"Storyboard.TargetName="PART_ContentPresenter"/></Storyboard></VisualState></VisualStateGroup><VisualStateGroup x:Name="FocusStates"><VisualState x:Name="Focused"/><VisualState x:Name="Unfocused"/></VisualStateGroup></VisualStateManager.VisualStateGroups><Rectangle Fill="Transparent"/><ContentPresenter x:Name="PART_ContentPresenter" Opacity="0.7" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/></Grid></ControlTemplate></Setter.Value></Setter></Style><Style x:Key="WPFDevelopersWindow" TargetType="{x:Type wpfdev:Window}" BasedOn="{x:Null}"><Setter Property="Foreground" Value="{DynamicResource PrimaryTextSolidColorBrush}" /><Setter Property="Background"  Value="{DynamicResource WhiteSolidColorBrush}" /><Setter Property="BorderBrush" Value="{DynamicResource PrimaryNormalSolidColorBrush}" /><Setter Property="BorderThickness"  Value="1" /><Setter Property="IsTabStop"  Value="False" /><Setter Property="ResizeMode" Value="CanResizeWithGrip" /><Setter Property="SnapsToDevicePixels" Value="True"/><Setter Property="UseLayoutRounding" Value="True" /><Setter Property="TextOptions.TextFormattingMode" Value="Ideal" /><Setter Property="WindowStyle"  Value="None" /><Setter Property="MaxHeight" Value="{x:Static SystemParameters.MaximizedPrimaryScreenHeight}"/><Setter Property="MaxWidth" Value="{x:Static SystemParameters.MaximizedPrimaryScreenWidth}"/><Setter Property="FontFamily" Value="{DynamicResource NormalFontFamily}" /><Setter Property="WindowChrome.WindowChrome"><Setter.Value><WindowChrome  GlassFrameThickness="0,0,0,1" UseAeroCaptionButtons="False"CaptionHeight="{Binding TitleHeight,RelativeSource={RelativeSource AncestorType=wpfdev:Window}}"/></Setter.Value></Setter><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type wpfdev:Window}"><Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"SnapsToDevicePixels="True"><Grid Background="{TemplateBinding Background}"><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="*" /><RowDefinition Height="Auto" /></Grid.RowDefinitions><Grid Grid.Row="0" Height="{TemplateBinding TitleHeight}" Background="{TemplateBinding BorderBrush}"><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition Width="*" /><ColumnDefinition Width="Auto" MinWidth="30"/></Grid.ColumnDefinitions><Image Source="{TemplateBinding Icon}" Stretch="Fill"VerticalAlignment="Center" HorizontalAlignment="Left" Width="30" Height="30" Margin="14,0,4,0"RenderOptions.BitmapScalingMode="HighQuality"/><TextBlock Text="{TemplateBinding Title}" x:Name="PART_Title"Foreground="{DynamicResource WhiteSolidColorBrush}" Grid.Column="1"VerticalAlignment="Center" FontSize="{DynamicResource TitleFontSize}"/><WrapPanel Grid.Column="2" WindowChrome.IsHitTestVisibleInChrome="True"><WrapPanel x:Name="PART_MinAndMax"><Button Name="PART_MinimizeButton"  IsTabStop="False"   Padding="0" Margin="0,6" Style="{StaticResource WindowButtonStyle}" ToolTip="Minimize"Command="SystemCommands.MinimizeWindowCommand"><Grid HorizontalAlignment="Center" VerticalAlignment="Center"><Rectangle x:Name="MinimizeGlyph"  Width="10"  Height="1"   Margin="0 7 0 0" VerticalAlignment="Bottom" Fill="{DynamicResource WhiteSolidColorBrush}" /></Grid></Button><Button Name="PART_MaximizeButton" IsTabStop="False"  Padding="0"Style="{StaticResource WindowButtonStyle}" Margin="0,6"ToolTip="Maximize"Command="SystemCommands.MaximizeWindowCommand"><Grid HorizontalAlignment="Center" VerticalAlignment="Center"><Path Width="10" Height="10"HorizontalAlignment="Center" VerticalAlignment="Center" Data="{DynamicResource PathMetroWindowMaximize}" Fill="{DynamicResource WhiteSolidColorBrush}"Stretch="Fill" UseLayoutRounding="False" /></Grid></Button><Button Name="PART_RestoreButton" IsTabStop="False"  Padding="0"Style="{StaticResource WindowButtonStyle}" Margin="0,6"ToolTip="Restore"Command="SystemCommands.RestoreWindowCommand"Visibility="Collapsed"><Grid HorizontalAlignment="Center" VerticalAlignment="Center"><Path Width="10" Height="10"HorizontalAlignment="Center" VerticalAlignment="Center" Data="{DynamicResource PathMetroWindowRestore}" Fill="{DynamicResource WhiteSolidColorBrush}"Stretch="Fill" UseLayoutRounding="False" /></Grid></Button></WrapPanel><Button Name="PART_CloseButton" Margin="0,6" ToolTip="Close"IsTabStop="False" Style="{StaticResource WindowButtonStyle}"Command="SystemCommands.CloseWindowCommand"><Path Width="10" Height="10"HorizontalAlignment="Center"VerticalAlignment="Center"Data="{DynamicResource PathMetroWindowClose}"Fill="{DynamicResource WhiteSolidColorBrush}"Stretch="Fill" /></Button></WrapPanel></Grid><AdornerDecorator Grid.Row="1" KeyboardNavigation.IsTabStop="False"Margin="4"><ContentPresenter x:Name="MainContentPresenter"/></AdornerDecorator><ResizeGrip x:Name="ResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="2" IsTabStop="False"Visibility="Collapsed"/></Grid></Border><ControlTemplate.Triggers><Trigger Property="WindowState" Value="Maximized"><Setter Property="Visibility" Value="Visible" TargetName="PART_RestoreButton"/><Setter Property="Visibility" Value="Collapsed" TargetName="PART_MaximizeButton"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property="ResizeMode"  Value="CanResizeWithGrip" /><Condition Property="WindowState"  Value="Normal" /></MultiTrigger.Conditions><Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" /></MultiTrigger><MultiTrigger><MultiTrigger.Conditions><Condition Property="ResizeMode"  Value="NoResize" /><Condition Property="WindowStyle"  Value="ToolWindow" /></MultiTrigger.Conditions><Setter TargetName="PART_MinAndMax" Property="Visibility" Value="Collapsed" /></MultiTrigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></ResourceDictionary>

三、创建MainWindow.xaml。

<ws:Window x:Class="Wpf45.MainWindow"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"xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"xmlns:local="clr-namespace:Wpf45"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid></Grid>
</ws:Window>

四、删除MainWindow.xaml.cs删除继承。

public partial class MainWindow {public MainWindow(){InitializeComponent();}}

02


效果预览

鸣谢素材提供者菜小松cc

源码地址如下

Github:https://github.com/WPFDevelopersOrg

Gitee:https://gitee.com/WPFDevelopersOrg

WPF开发者QQ群: 340500857 

Github:https://github.com/WPFDevelopersOrg

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/WPFDevelopersOrg

55d4dbc9dbd93c42bb4226cfd590c80c.png

扫一扫关注我们,

32c4cdd0466337b43a55b6e7bcba7b4e.gif

更多知识早知道!

1a2e9cf5c1ad64b9f686e13798e6c3dd.gif

点击阅读原文可跳转至源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291728.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ngModel 值不更新/显示

angular中的$scope是页面&#xff08;view&#xff09;和数据&#xff08;model&#xff09;之间的桥梁&#xff0c;它链接了页面元素和model&#xff0c;也是angular双向绑定机制的核心。 而ngModel是angular用来处理表单&#xff08;form&#xff09;的最重要的指令&#xff…

go获取项目内所有proto_gRPC学习之三:初试GO版gRPC开发

欢迎访问我的GitHubhttps://github.com/zq2599/blog_demos内容&#xff1a;所有原创文章分类和汇总&#xff0c;及配套源码&#xff0c;涉及Java、Docker、Kubernetes、DevOPS等&#xff1b;本篇概览本文《gRPC学习》系列的第三篇&#xff0c;前文已准备好gRPC开发环境&#xf…

服务端架构中的“网关服务器”

这么一个场景&#xff1a;一个要承载高并发、具有高性能的后台服务&#xff0c;往往会有多个不同的应用服务。问题来了&#xff0c;你会怎样设计架构呢&#xff1f;如下图所示&#xff0c;为了共用一个稳定高效的网络处理功能&#xff0c;把所有服务写在一个进程里。接下来悲剧…

一起来庆祝 .NET 20 周年!

你知道吗&#xff1f;.NET 将要迎来 20 周年, 在 20 年前的 2002 年, 微软公布了下一代的软件、服务的愿景和路线&#xff0c;2 月 13 日&#xff0c;Visual Studio .NET 推出&#xff0c;.NET 开发平台的第一个版本正式向世界发布。而现在, .NET 6 成为统一的开发平台&#xf…

不固定图片宽高瀑布流_APP设计学习:瀑布流式的产品UI设计

看到好的APP产品UI设计&#xff0c;真是忍不住想要停留几秒&#xff0c;慢慢来欣赏。今天学堂君收集了近期不错的优质的APP设计作品&#xff0c;看起来极舒服的UI界面&#xff0c;分享给大家。这一期的重点学习&#xff1a;在APP界面设计当中&#xff0c;如何应用瀑布流式的布局…

【Blog.Core开源】网关自定义认证鉴权与传参

书接上文&#xff0c;上回咱们说到了《【Blog.Core开源】网关统一集成下游服务文档》&#xff0c;已经将多个下游服务统一集成到了网关里&#xff0c;并且也把接口文档Swagger给集成了&#xff0c;那今天就说一下认证和鉴权相关的话题。继续说下故事背景在平时开发的时候&#…

HDFS HA与QJM(Quorum Journal Manager)介绍及官网内容整理

问题导读1.HDFS HA与QJM解决了什么问题&#xff1f; 2.HDFS HA与QJM区别是什么&#xff1f; 3.在HA&#xff08;两个namenode&#xff09;架构下&#xff0c;如何访问hdfs文件&#xff1f;【使用QJM构建HDFS HA架构(2.2)】本文主要介绍HDFS HA特性&#xff0c;以及如何使用QJM(…

#时间预测算法_【时间序列】时序预测竞赛之异常检测算法综述

本文将介绍在时间序列预测相关问题中常见的异常检测算法&#xff0c;可以很大程度上帮助改善最终预测效果。异常分类时间序列的异常检测问题通常表示为相对于某些标准信号或常见信号的离群点。虽然有很多的异常类型&#xff0c;但是我们只关注业务角度中最重要的类型&#xff0…

监测利器cacti服务安装

1、Cacti原理及概述1Cacti是一款使用PHP语言开发的性能与流量监测工具。监测的对象可以是linux也可以是windows也可以是路由器交换机等网络设备主要基于SNMPsimple network managerprotocol简单网络管理协议来搜集cpu占用内存使用运行进程数磁盘空间网卡流量等各种网络数据。2实…

C#中的类型转换

前几篇文章中经常说到强制类型转换&#xff0c;就是可以将派生类对象强制转换为基类对象的做法或者通过as运算符进行的转换。今天我们就来一起简单了解复习下在C#中都有哪些类型的转换。要理解转换很容易&#xff0c;日常的开发编码过程中&#xff0c;由于变量类型的不同我们可…

linux之快速过滤文本的关键字以及快速过滤目录下的关键字

1、快速过过滤文本的关键字 cat file | grep 关键字 比如Android日志文件很长&#xff0c;需要过滤Exception,就可以用这个办法&#xff0c;如下图 2、快速过滤目录下的关键字 grep -r 关键字 比如我们在linux上看目录下哪些关键字段&#xff0c;好像开发工具里面的 find usag…

hadoop使用

2019独角兽企业重金招聘Python工程师标准>>> 框架简介 Hadoop使用主/从&#xff08;Master/Slave&#xff09;架构&#xff0c;主要角色有NameNode&#xff0c;DataNode&#xff0c;secondary NameNode&#xff0c;JobTracker&#xff0c;TaskTracker组成。 其中Nam…

bigint hive java类型_详解Apache Hudi如何配置各种类型分区

1. 引入Apache Hudi支持多种分区方式数据集&#xff0c;如多级分区、单分区、时间日期分区、无分区数据集等&#xff0c;用户可根据实际需求选择合适的分区方式&#xff0c;下面来详细了解Hudi如何配置何种类型分区。2. 分区处理为说明Hudi对不同分区类型的处理&#xff0c;假定…

C#中的命名空间和程序集

前言今天这篇文章和大家一起学习下C#语言下的命名空间和程序集。在日常的编码工作中&#xff0c;我们对命名空间和程序集都不会很陌生。在创建项目文件时&#xff0c;IDE自动会为我们创建好一个大的命名空间和程序集。大多数业务代码都是在解决方案下各自的命令空间里进行编码的…

基于jQuery的ajax系列之用FormData实现页面无刷新上传

接着上一篇ajax系列之用jQuery的ajax方法向服务器发出get和post请求写&#xff0c;这篇主要写如何利用ajax和FormData实现页面无刷新的文件上传效果&#xff0c;主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的FormData接口。关于FormData&#xff0c;大家可以看MDN文…

abd shell关闭所有程序_在后台服务器上运行程序

之前总结过screen的用法&#xff0c;但还可以用nohup命令。nohup工具&#xff1a;Linux系统中有提供一个很好的不挂断地运行命令——nohup。我们使用nohup能很简单的控制使用&#xff0c;在此就简单的介绍一下nohup工具。nohup 命令nohup就是不挂起的意思( no hang up)。用途&a…

解锁JDK 12的奇妙之旅:新特性详解

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 解锁JDK 12的奇妙之旅&#xff1a;新特性详解 前言switch表达式拓展NumberFormat对复杂数字的格式化字符串支持transform、indent操作新增方法Files.mismatch(Path, Path)Teeing Collector支持unicode…

.NET6之MiniAPI(十四):跨域CORS(上)

为了说明跨请求&#xff0c;创建了两个项目&#xff0c;一个mini api&#xff0c;端口是5001&#xff0c;另一个razor page项目&#xff0c;端口是5280。5280项目会在页面用ajax的方式来请求5001&#xff0c;形成跨域请求&#xff0c;由于是本地测试&#xff0c;host都是localh…

django model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

2019独角兽企业重金招聘Python工程师标准>>> 1.多表连接查询&#xff1a;当我知道这点的时候顿时觉得django太NX了。 class A(models.Model): name models.CharField(u名称) class B(models.Model): aa models.ForeignKey(A)B.objects.filter(aa__name__c…

利用tabluea分析数据的案例_利用德温特分析Dartsip的案例检索结果

德温特创新平台(Derwent Innovation)与Darts-ip知识产权案例数据库均是科睿唯安旗下的知识产权数据库&#xff0c;虽然这两个数据库的侧重点分别在于专利信息与知识产权判例&#xff0c;但若将两者结合使用则能发挥11>2的作用&#xff0c;打通专利全生命周期。关注我们的朋友…