- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
先看效果图:
大致思路是:通过反射获取Popup内部的原生窗口句柄,然后通过前文已经实现的WindowMaterial类来应用窗口特效;对于ToolTip,为了保持其易用性,我使用了附加属性+全局样式的方式来实现,ToolTip也是一个特殊的Popup. 前文链接:WPF 模拟UWP原生窗口样式——亚克力|云母材质、自定义标题栏样式、原生DWM动画 (附我封装好的类) 本文的Demo:
TwilightLemon/WindowEffectTest: 测试win10/11的模糊效果 (github.com) 。
通过查阅.NET源码得知,Popup内部通过一个类型为PopupSecurityHelper的私有字段_secHelper来管理窗口hWnd,并且在创建完成之时会触发Popup.Opened事件。 通过反射来获取窗口句柄
const BindingFlags privateInstanceFlag = BindingFlags.NonPublic | BindingFlags.Instance; public static IntPtr GetNativeWindowHwnd(this Popup popup) { //获取Popup内部的_secHelper字段Info var field = typeof(Popup).GetField("_secHelper", privateInstanceFlag); if (field != null) { //获取popup的_secHelper字段值 if (field.GetValue(popup) is { } _secHelper) { //获取_secHelper的Handle属性Info if (_secHelper.GetType().GetProperty("Handle", privateInstanceFlag) is { } prop) { if (prop.GetValue(_secHelper) is IntPtr handle) { //返回句柄 return handle; } } } } //未找到 return IntPtr.Zero; }
同样地,能在ToolTip内部找到私有字段_parentPopup 。
public static IntPtr GetNativeWindowHwnd(this ToolTip tip) { var field=tip.GetType().GetField("_parentPopup", privateInstanceFlag); if (field != null) { if(field.GetValue(tip) is Popup{ } popup) { return popup.GetNativeWindowHwnd(); } } return IntPtr.Zero; }
有了窗口句柄那么一切都好办了,直接调用我封装好的WindowMaterial类,如果你想了解更多请查看前文.
public static void SetPopupWindowMaterial(IntPtr hwnd,Color compositionColor, MaterialApis.WindowCorner corner= MaterialApis.WindowCorner.Round) { if (hwnd != IntPtr.Zero) { int hexColor = compositionColor.ToHexColor(); var hwndSource = HwndSource.FromHwnd(hwnd); //---- MaterialApis.SetWindowProperties(hwndSource, 0); MaterialApis.SetWindowComposition(hwnd, true, hexColor); //---- MaterialApis.SetWindowCorner(hwnd, corner); } }
根据微软的设计规范,这里默认对普通Popup使用圆角,对ToolTip使用小圆角,使用亚克力材质并附加compositionColor。 在github中获取完整的WindowMaterial.cs,我可能会不定期地更新它:WindowEffectTest/WindowMaterial.cs at master · TwilightLemon/WindowEffectTest (github.com) 。
如果你想使用Mica或MicaAlt等材质则将上面框起来的代码替换为:
MaterialApis.SetWindowProperties(hwndSource, -1); MaterialApis.SetBackDropType(hwnd, MaterialType.Mica); MaterialApis.SetDarkMode(hwnd, isDarkMode: true);
在Demo中查看封装好的类:WindowEffectTest/FluentPopup.cs at master · TwilightLemon/WindowEffectTest (github.com) 。
最后此篇关于WPF中为Popup和ToolTip使用WindowMaterial特效win10/win11的文章就讲到这里了,如果你想了解更多关于WPF中为Popup和ToolTip使用WindowMaterial特效win10/win11的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!