前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF 修复 ContextMenu 在开启 PerMonitorV2 后所用 DPI 错误

WPF 修复 ContextMenu 在开启 PerMonitorV2 后所用 DPI 错误

作者头像
林德熙
发布2023-04-07 08:48:56
3820
发布2023-04-07 08:48:56
举报
文章被收录于专栏:林德熙的博客

本文告诉大家如何修复 WPF 的 ContextMenu 在开启 PerMonitorV2 之后,在双屏不同的 DPI 的设备上,在副屏弹出的 ContextMenu 使用了主屏的 DPI 导致缩放错误的问题

关于什么是 PerMonitorV2 请参阅 支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发 - walterlv

开启 PerMonitorV2 的 WPF 应用的 ContextMenu 将在多屏下,需要找到一个关联的屏幕来辅助计算所要显示的坐标。然而在 ContextMenu 创建出来时,是无法知道应该选用哪个屏幕。这就是导致 ContextMenu 视觉效果的 DPI 缩放不对的原因

修复方法就是给 ContextMenu 一个参考的控件,通过此参考控件,可以让 ContextMenu 进行多屏幕不同的 DPI 计算。给 ContextMenu 一个参考的控件的方法有两个

第一个方法是通过将 ContextMenu 设置给所要关联的控件的 ContextMenu 属性上,如此即可让 ContextMenu 弹出的坐标可以根据此关联控件计算。要求关联的控件是在界面布局

代码语言:javascript
复制
            var menu = new ContextMenu
            {
                Name = menuName,
                Style = contextMenuStyle,
                ItemsSource = menuItems,
            };
            canvas.ContextMenu = menu;

但是以上方法存在缺点,那就是对相同的业务逻辑,在 ContextMenu 关闭之前重新赋值,将存在重入问题,重入问题也许导致了某个过程的 ContextMenu 依然由于找不到关联的控件,弹出在左上角。例如以上代码被快速进入两次,第一次的 ContextMenu 对象还没完成弹出,第二次就进入,第二次的 ContextMenu 将会覆盖 canvas 的 ContextMenu 属性,从而让第一次的 ContextMenu 找不到关联的控件,让第一次的 ContextMenu 弹出到左上角,或者计算 DPI 不对

如果采用第一个方法,可以通过缓存 ContextMenu 的方式,代替每次都创建。或者判断当前正在准备弹出 ContextMenu 就不继续创建

第二个方法是设置 ContextMenu 的 PlacementTarget 属性,通过此属性可以让 ContextMenu 关联控件,如以下代码

代码语言:javascript
复制
            var menu = new ContextMenu
            {
                Name = menuName,
                Style = contextMenuStyle,
                ItemsSource = menuItems,
                // Popup 内部不处理显示过程中的 DPI 改变,依赖于创建时要能找到正确的屏幕,
                // 如果什么都不指定,那么创建会创建到主屏,如果实际显示在副屏了,那就会因为 DPI 缩放导致尺寸不对。
                // 
                // 寻找创建时的屏幕时,会寻找 PlacementTarget 和 VisualTreeHelper.GetContainingVisual2D(VisualTreeHelper.GetParent(this)),
                // 这里通过指定 PlacementTarget 确保创建的屏幕正确
                PlacementTarget = canvas,
            };
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档