WPF 使用WindowChrome自定义窗体 保留原生窗体特性
本文大幅度借鉴dino.c大佬的文章
https://www.cnblogs.com/dino623/p/uielements_of_window.html
https://www.cnblogs.com/dino623/p/problems_of_WindowChrome.html
https://www.cnblogs.com/dino623/p/custom_window_style_using_WindowChrome.html
我在这里汇总一下,属于粘了就能用那种。在预设100,125,150,175DPI下最大化也能正常显示。
不懂的地方可以阅读上面的文章
说到原生窗体的特性都有什么 咱来做个对比 大家来感受下
使用WindowChrome

使用WindowStyle="None"

使用WindowChrome的时候 无需设置就保留了原生阴影、拖拽、交互动画
而使用WindowStyle="None"的话,会发现最大化的时候会覆盖任务栏。
想要实现原生的样式就需要自己手写。
这些功能可以实现吗?能实现。效果好吗? 不一定,像我这种WPF玩的不专业的人很难实现这些功能,啥玩意都得上网扒拉,对不对路还不一定那网上都花里胡哨的一人一种写法,这就很闹心。
<Window x:Class="RouteWPF.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"
mc:Ignorable="d"
Title="MainWindow" SnapsToDevicePixels="True" StateChanged="Window_StateChanged" Loaded="Window_Loaded">
<WindowChrome.WindowChrome>
<WindowChrome UseAeroCaptionButtons="False" NonClientFrameEdges="None" CaptionHeight="40" />
</WindowChrome.WindowChrome>
<Grid x:Name="grdMain" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#C62F2F">
<WrapPanel Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,10,0">
<Button x:Name="btnMin" Style="{DynamicResource MinButton}" Click="BtnMin_Click"/>
<Button x:Name="btnNorm" Style="{DynamicResource MaxButton}" Margin="3,0,0,0" Click="BtnNorm_Click"/>
<Button x:Name="btnClose" Style="{DynamicResource CloseButton}" Margin="3,0,0,0" Click="BtnClose_Click"/>
</WrapPanel>
</Grid>
<Grid Grid.Row="1" Background="#FFFFFF">
<Border BorderThickness="1" BorderBrush="#C62F2F"/>
</Grid>
</Grid>
</Window>
UseAeroCaptionButtons 表示是对 Windows Aero 标题按钮启用的命中测试是否可用。默认值为True
NonClientFrameEdges 获取或设置一个值,该值表示窗口框架边缘是否归客户端所有。默认值为None
CaptionHeight 表示窗体菜单栏高度,我这里设置跟Gird里第一行高度一致,代表自定义的菜单栏
注意下,我在放置按钮的WrapPanel容器中设置了 WindowChrome.IsHitTestVisibleInChrome,该值表示 WPF 命中测试在窗口非工作区中的元素是否可用。默认值为False
接下来是后台代码
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input; namespace WpfApp1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
int paddings = ;
public MainWindow()
{
InitializeComponent();
} private void Window_Loaded(object sender, RoutedEventArgs e)
{
paddings = ;
} private void Window_StateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized)
{
Thickness thickness = SystemParameters.WindowResizeBorderThickness;
grdMain.Margin = new Thickness(thickness.Left + paddings, thickness.Top + paddings, thickness.Right + paddings, thickness.Bottom + paddings);
}
else
{
grdMain.Margin = new Thickness();
}
} private void BtnMin_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
} private void BtnClose_Click(object sender, RoutedEventArgs e)
{
Close();
} private void BtnNorm_Click(object sender, RoutedEventArgs e)
{
if (WindowState == WindowState.Normal)
{
btnNorm.Style = (Style)FindResource("NormButton");
WindowState = WindowState.Maximized;
}
else
{
btnNorm.Style = (Style)FindResource("MaxButton");
WindowState = WindowState.Normal;
}
}
}
}
这里的paddings我默认设置为4,这里需要借鉴下大佬的第一、二篇文章,里面很清晰的解释道为啥设置为4。
完整看过第二篇文章的会发现无法直接获取SM_CXPADDEDBORDER的值。
我查了官网文档user32.dll里面有函数可以取值,https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-getsystemmetrics。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetSystemMetrics(int index);
只不过按照这个取值来的话125往上的DPI最大化显示不正常,边框会比之前厚,咱就默认4就行。
WPF 使用WindowChrome自定义窗体 保留原生窗体特性的更多相关文章
- [WPF]使用WindowChrome自定义Window Style
1. 前言 做了WPF开发多年,一直未曾自己实现一个自定义Window Style,无论是<WPF编程宝典>或是各种博客都建议使用WindowStyle="None" ...
- WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)
WPF 自定义窗口样式有多种方式,不过基本核心实现都是在修改 Win32 窗口样式.然而,Windows 上的应用就应该有 Windows 应用的样子嘛,在保证自定义的同时也能与其他窗口样式保持一致当 ...
- [WPF自定义控件]使用WindowChrome自定义Window Style
1. 为什么要自定义Window 对稍微有点规模的桌面软件来说自定义的Window几乎是标配了,一来设计师总是克制不住自己想想软件更个性化,为了UI的和谐修改Window也是必要的:二来多一行的空间可 ...
- [WPF自定义控件]?使用WindowChrome自定义Window Style
原文:[WPF自定义控件]?使用WindowChrome自定义Window Style 1. 为什么要自定义Window 对稍微有点规模的桌面软件来说自定义的Window几乎是标配了,一来设计师总是克 ...
- C#自定义Winform无边框窗体
C#自定义Winform无边框窗体 在实际项目中,WinForm窗体或者控件不能满足要求,所以就需要自己设计窗体等,当然设计界面可以用的东西很多,例如WPF.或者一些第三方的库等.本例中将采用WinF ...
- C#自定义无边框MessageBox窗体
C#自定义无边框MessageBox窗体 本例子中制作一个无边框的MessageBox窗体 展示效果: 窗体设计 1.添加一个窗体继承原生Form public partial class Messa ...
- WPF实用指南二:移除窗体的图标
原文:WPF实用指南二:移除窗体的图标 WPF没有提供任何功能来移除窗体上的icon图标.一般的做法是设置一个空白的图标,如下图1: 这种做法在窗体边框与标题之间仍然会保留一片空白. 比较好的做法是使 ...
- WPF 利用子线程弹出子窗体的研究
一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了. ...
- 在Office应用中打开WPF窗体并且让子窗体显示在Office应用上
在.NET主程序中,我们可以通过创建 ExcelApplication 对象来打开一个Excel应用程序,如果我们想在Excle里面再打开WPF窗口,问题就不那么简单了. 我们可以简单的实例化一个WP ...
随机推荐
- PDOStatement::debugDumpParams
PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令(PHP 5 >= 5.1.0, PECL pdo >= 0.9.0) 说明 语法 bool P ...
- 电脑小知识:Windows 10是用什么语言写的?到底有多少行代码?
这是微软的内核工程师 Axel Rietschin在Quora的一个回答. Windows 10 的code base 和Windows 8.x , 7 , Vista , XP , 2000 和Wi ...
- 4.28 省选模拟赛 负环 倍增 矩阵乘法 dp
容易想到 这个环一定是简单环. 考虑如果是复杂环 那么显然对于其中的第一个简单环来说 要么其权值为负 如果为正没必要走一圈 走一部分即可. 对于前者 显然可以找到更小的 对于第二部分是递归定义的. 综 ...
- [C#] (原创)一步一步教你自定义控件——01,TrackBar
一.前言 技术没有先进落后之分,只有合不合适. WinForm有着非常多的优点,在使用WinForm久了之后,难免会觉得WinForm自带的某些控件外观上有些许朴素.或者功能上有些不如意,自然而然便想 ...
- 最优化算法【牛顿法、拟牛顿法、BFGS算法】
一.牛顿法 对于优化函数\(f(x)\),在\(x_0\)处泰勒展开, \[f(x)=f(x_0)+f^{'}(x_0)(x-x_0)+o(\Delta x) \] 去其线性部分,忽略高阶无穷小,令\ ...
- PV与UV你的网站也可以
个人博客网站分析 阅读前面的文章,有助于理解本文. 1.是时候来一个个人博客网站了 2.什么?你还没有自己的域名? 3.你的个人博客网站该上线了! 为什么需要流量分析? 各位小伙伴,请看下图,你们发现 ...
- Requests接口测试库-官网快速上手
Requests 一个发送HTTP请求的库基于urllib3,相比自带的库,提供了更高效简洁的可用方法,测试从业者用来做接口测试的一个好工具 文章内容均来自官网:https://requests.re ...
- Python多线程-ThreadLocal
参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017630786314240#0 ThreadLocal ThreadLocal变量虽然是 ...
- 阿里Canal中间件的初步搭建和使用
一.前言 Binlog是MySQL数据库的二进制日志,用于记录用户对数据库操作的SQL语句(除了数据查询语句)信息.而Binlog格式也有三种,分别为STATEMENT.ROW.MIXED.STATM ...
- 100行Python代码实现一款高精度免费OCR工具
近期Github开源了一款基于Python开发.名为 Textshot 的截图工具,刚开源不到半个月已经500+Star. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语 ...