WPF 修改屏幕DPI,会触发控件重新加载Unload/Load
修改屏幕DPI,会触发控件的Unloaded/Loaded
现象/重现案例
这里简单介绍下,修改屏幕DPI,触发Unloaded/Loaded的神奇案例
1. 我们新建一个窗口,添加一个UserControl1,然后在UserControl1中添加UserControl2
<Window x:Class="WPFUnloadedTriggerTest.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:local="clr-namespace:WPFUnloadedTriggerTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<local:UserControl1></local:UserControl1>
</Window>
------------------------------我是分隔线-----------------------------------
<UserControl x:Class="WPFUnloadedTriggerTest.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFUnloadedTriggerTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<local:UserControl2></local:UserControl2>
</UserControl>

2. 显示窗口后,修改DPI比例

3. 设置完后,会触发Unloaded/Loaded重新加载
Unloaded的触发顺序是UserControl1-->UserControl2,Window并不会触发Unloaded事件!
是不是诡异?我们继续。。。
4. Window我们添加一个ControlTemplate模块
<Window.Template>
<ControlTemplate TargetType="Window">
<Border>
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
</ControlTemplate>
</Window.Template>
再重复2、3步骤,Unloaded的触发顺序变了:
触发UserControl2的Unloaded,Window、UserControl1并不会触发Unloaded事件!
问题分析
第2步骤中修改DPI后,Unloaded事件不一定触发。如何必现呢?
将窗口靠近到任务栏上方,再修改文本比例。

我们查看调用堆栈,貌似是系统给窗口发送消息然后调用BroadcastUnloadedEvent事件,触发Unload

所以应该是修改DPI,窗口宽高超出了当前屏幕尺寸范围,系统对UserControl的视觉树进行重新加载布局。
至于窗口没有触发Unloaded、以及在窗口添加以上模块后下一级子控件也没有触发Unloaded事件的原因,暂不了解
而对WPF-Unloaded/Loaded的已知情况如下:
- FrameworkElement, 第一次加载显示时,会触发Loaded。元素被释放时,会触发Unloaded。窗口Show/Close时,视觉树变化都会触发加载事件
- MenuItem, 在FrameworkElement基础上,每次和隐藏MenuItem时,会额外触发Load/Unloaded
- TabControl,当你选中一个tabItem时会触发Loaded,当你取消选中一个tabItem时会触发Unloaded,所以切换Tab时必定有一个Loaded一个Unloaded。
- Expander,每次被Expanded扩展时会引发Loaded,但当隐藏时不会引发Unloaded。
以上问题的解决方案?暂时没有解决方案,只有规避措施,不要过于依赖于Unload/Loaded,而且使用了Unload/Loaded时也要添加注销机制,防止重入
我在github提了个issue:After Modified screen dpi,Unloaded/Loaded is trigged unexpectedly
WPF 修改屏幕DPI,会触发控件重新加载Unload/Load的更多相关文章
- 重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图
原文:重新想象 Windows 8.1 Store Apps (81) - 控件增强: 加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 Web ...
- Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子
Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子 procedure TForm1.Button1Click(Sender: TObject); ...
- easyui控件的加载顺序
使用easyui做布局时,会模仿窗口程序界面,做出一些较复杂的布局.按由外层到内层的顺序: (最外层)panel->tabs->tabs1 ->tabs2->layout-&g ...
- 使用DevExpress.XtraTabbedMdi.XtraTabbedMdiManager控件来加载MDI窗体
使用DevExpress.XtraTabbedMdi.XtraTabbedMdiManager控件来加载MDI窗体 [csharp] view plaincopyprint? <SPAN ...
- 在WinForm应用程序中,使用选项卡控件来加载不同的Form界面!
TabPage tp=new TabPage(); your选项卡控件.Controls.Add(tp); From1 frm=new Form1(); frm.TopLevel = false; f ...
- Asp.net 的DropDownList 控件动态加载
在做连接数据库表,在页面上用DropDownList 下拉框查询某条数据时,因为数据库里的数据,随时都有可能增加或减少,而下拉框关联的某个字段的值并不一定是固定的. 表信息: CREATE TABLE ...
- 【高德地图API】Pivot控件中加载地图并禁止Pivot手势
如题,解决方案,参考[Windows phone应用开发[20]-禁止Pivot手势]http://www.cnblogs.com/chenkai/p/3408658.html. xaml代码清单 ...
- WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案
首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如 WPF中不规则窗体与WebBrowser控件的兼 ...
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...
随机推荐
- Java Web(1)高并发业务
互联网无时无刻不面对着高并发问题,例如商品秒杀.微信群抢红包.大麦网抢演唱会门票等. 当一个Web系统,在一秒内收到数以万计甚至更多的请求时,系统的优化和稳定是至关重要的. 互联网的开发包括Java后 ...
- vue-cli3安装jQuery
注:vue-cli3.0 没有了 webpack.config.js 配置文件,取而代之的是集合在 vue.config.js文件 内进行配置 默认已经安装好vue-cli3.0项目 step1:命令 ...
- PCES - alpha阶段测试报告
测试计划 测试目的 本测试目的在于测试项目完成情况,以及分析测试结果,为下一轮开发提供解决方案 测试项目 学生用户登录测试 课程信息检索测试 服务器测试 在测试过程中出现的Bug 用户界面间的跳转逻辑 ...
- Linux读取外存
Linux系统不像Windows系统那样,U盘自动识别,即插即用,Linux需要手动挂载U盘.步骤如下: 1.查看闪存: fdisk -l 2.添加挂载目录,一般放在/mnt下 mkdir /mnt/ ...
- python中的列表list练习
列表: 1.增 1.1 append,在列表的末尾追加元素,使用方法:list.append('元素') li = ['alex', 'wusir', 'eric', 'rain', 'alex'] ...
- 原生js实现上拉加载
原生js实现上拉加载其实超级简单,把原理整明白了你也会,再也不用去引一个mescroll啦~ 好了,废话不多说,开始进入正题:上拉加载是怎么去做的,原理就是监听滚动条滑到页面底部,然后就去做一次请求数 ...
- Ambari 集群时间同步配置教程
本文原始地址:https://sitoi.cn/posts/27560.html 步骤 在时间同步主节点创建 ntp.conf 文件 在时间同步从节点上创建 ntp.conf 文件 修改所有节点时区 ...
- Django学习day1——Django的简单介绍
1.了解Web基本的开发 使用Python开发Web,最简单,原始和直接的办法是使用CGI标准现在从应用角度解释它是如何工作: 首先做一个Python脚本,输出HTML代码,然后保存成.cgi扩展名的 ...
- nginx篇最初级用法之lnmp环境搭建
这里m使用mariadb 需要下列软件列表: nginx mariadb 数据库客户端软件 mariadb-server 数据库服务器软件 mariadb-devel 其他客户端软件的依 ...
- js中关于执行的顺序及变量存放方式的一点记录
Markdown在线编辑器 - www.MdEditor.com 1 首先关于数据类型,有基本数据类型,和引用数据类型 基本数据类型有:number,string,boolean等:引用数据类型一般指 ...