我昨天和头像大人在解决一个坑,发现调用了 InvalidateVisual 的时候,不会触发 OnRender 方法。那么在什么时候会触发 OnRender 方法,在什么时候不会触发

在 WPF 中通过 InvalidateVisual 方法可以告诉 WPF 框架,当前这个控件需要重新绘制元素,但是调用这个方法不是立刻进行绘制,不然性能就太差了。而是等待 WPF 的下一次更新界面就会触发控件的刷新

换句话说,在调用 InvalidateVisual 方法的时候不会立刻触发 OnRender 方法,需要等待下一次的 Dispatcher 的 Render 优先级的任务触发的时候才会调用

但是本文解决的问题是,为什么调用 InvalidateVisual 方法的时候,等待下一次的 Dispatcher 或等很久都没有进入 OnRender 方法

先通过一个简单的代码让大家能测试 WPF 的行为

本文的代码放在 github 欢迎小伙伴访问

我创建了 Foo 类,继承 FrameworkElement 类,这样就能让这个 Foo 使用十分底层的方法,也减少了 WPF 框架的其他业务逻辑

我重写了 OnRender 方法,在里面随意显示了一个文本,触发了一个事件。触发事件的作用是让我上层可以知道这个控件触发了 OnRender 方法

    public class Foo : FrameworkElement{public event EventHandler Render;/// <inheritdoc />protected override void OnRender(DrawingContext drawingContext){Render?.Invoke(this, null);var formattedText = new FormattedText($"lindexi", CultureInfo.CurrentCulture, FlowDirection.LeftToRight,new Typeface(new FontFamily("微软雅黑"), new FontStyle(), new FontWeight(), new FontStretch()), 25,new SolidColorBrush(Colors.Black), 96);drawingContext.DrawText(formattedText, new Point());base.OnRender(drawingContext);}}

然后写一个简单的界面,这个界面包含 Foo 控件,和一个文本控件,在文本控件其实就是在 Foo 的渲染方法触发的时候给出当前刷新的时间

还有几个按钮分别是调用 InvalidateVisual 和控件是否可以显示等属性

此时可以看到点击 InvalidateVisual 按钮默认会触发 OnRender 方法,可以在界面的文本控件的时间看到,点击按钮之后时间更新

而如果此时点击 Collapsed 按钮,然后点击 InvalidateVisual 可以看到时间没有更新,也就是 OnRender 没有触发

原理是在控件的 OnRender 触发条件是控件需要在视觉树上,如果控件不在视觉树上,如被从上层元素移除或元素被设置 Collapsed 那么 OnRender 将不会触发

为什么此时设计让 OnRender 不触发?原因是既然这个控件就不想显示出来了,那么还调用他的 OnRender 方法做什么。此时调用渲染方法执行的结果又没有用户视觉反馈,相当于无用的功能,这就和条件判断的自动跳过执行代码一样的做法

所以在元素不在视觉树上以及元素被 Collapsed 将不调用 OnRender 方案是设计如此

这也就是为什么说不要在 OnRender 里面写业务代码的原因,因为 OnRender 作用只是用来绘制界面,而其他业务都应该和 OnRender 无关。我和头像遇到的问题是我逗比在 OnRender 写了业务代码,就像本文的例子程序一样,添加了一个事件,然后发现事件不触发。进一步可以告诫小伙伴,遵循规范可以少踩一些坑,不遵循规范可以了解更多的细节

有没有例外项?有的,如果使用 VisualBrush 获取元素的显示状态,那么此时的元素即使不在视觉树上也能进行显示,当然这也就出现了 VisualBrush 的内存泄漏问题了,详细请看 wpf VisualBrush 已知问题

那么如果是选择 Hide 呢?其实选择 Hide 只是元素不可见,本身元素还是在视觉树上面的,所以此时的渲染方法还是会被调用

注意本文说的 OnRender 方法为渲染方法这个说法不准确,应该是指导渲染方法

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

如有不方便在博客评论的问题,可以加我 QQ 2844808902 交流


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。


http://www.taodudu.cc/news/show-5712474.html

相关文章:

  • dotnet 一些代码审查套路
  • 2019-7-31-程序猿修养-日志应该如何写
  • 2019-11-29-程序猿修养-日志应该如何写
  • 计算机考试报名无法上传照片,操作令人窒息!报名计算机考试照片上传成逗比表情包...
  • 音标和发音
  • 家装网络布线小结
  • 数据结构课程设计:室内布线
  • Nyoj38布线问题
  • 家居装修布线先行 家庭布线工程全攻略
  • zipkin注册Nacos
  • Zipkin链路追踪
  • 对于电脑玩手游绝地求生:刺激战场吃鸡的几点建议
  • 计算机开关机讲解教程,电脑开机关机的几种方法,计算机电源键鼠标键盘网络唤醒图文教程...
  • win7 计算机设置命令,win7关机命令在哪里(附win7电脑键盘关机的操作方法)
  • Win10的两个实用技巧系列之切换用户登录、强制关机
  • 学生用计算机怎么关机6,电脑键盘怎么关机 手动解决很方便【图文】
  • 电脑关机重启 鼠标键盘不能用解决方法
  • 系统如何使用键盘快捷关机
  • 网易云,QQ音乐,Apple music 网页端下载音乐方法摸索
  • html分享音乐至qq,如何跨平台分享音乐?网易云音乐分享给QQ好友的方法
  • 给奶茶穿秋裤?美团外卖太会玩了!
  • 2013到2018年,IE又经历什么,让他快乐E去不复返?
  • 关于各种视频网站去广告
  • 最新手机制作抖音/西瓜沙雕动态漫画教程打包+素材
  • elisp 漫画教程
  • “错误 1067:进程意外终止”的原因和解决方案
  • mysql1067 aborting,Mysql 1067 错误解决方案汇总 | 吴小强的博客
  • FME常用转换器汇总
  • fme创建自定义转换器
  • python获取excel表头文件名称及名称中的年份

WPF 调用 InvalidateVisual 不触发 OnRender 的原因相关推荐

  1. 我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案...

    几个星期之前写了一篇关于如何通过WCF进行 双向通信的文章([原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communication) ),在文章中我提供了一个如 ...

  2. 调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配

     调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配.请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 用c#调用视频接口相关的dll,dll ...

  3. WPF 窗口居中 变更触发机制

    原文:WPF 窗口居中 & 变更触发机制 窗口居中 & 变更触发机制 解决: 1.单实例窗口,窗口每次隐藏后再显示时,位置居中显示 2.多屏幕下单实例窗口,当父窗口移动到其它屏幕时,单 ...

  4. 【转】WPF调用图片路径,或资源图片

    转自:https://www.cnblogs.com/sntetwt/p/5402098.html 一.加载本项目的图片 WPF引入了统一资源标识Uri(Unified Resource Identi ...

  5. WPF圆角按钮与触发颜色变化

    原文:WPF圆角按钮与触发颜色变化 <Button x:Name="button1" Content="按钮1" Margin="10,10,0 ...

  6. WPF调用图片路径,或资源图片

    一.加载本项目的图片 WPF引入了统一资源标识Uri(Unified Resource Identifier)来标识和访问资源. 其中较为常见的情况是用Uri加载图像.Uri表达式的一般形式为:协议+ ...

  7. 2021-10-18 WPF调用dll出现异常

    问题:WPF调用其他托管dll时,提示System.Windows.Markup.XamlParseException异常 用VS2019新建了一个wpf程序,调用已经写好的类库dll时,提示异常,见 ...

  8. 关于ios最新系统[我是ios13.3]开发摇一摇的时候无法触发devicemotion的原因

    关于ios最新系统[我是ios13.3]开发摇一摇的时候无法触发devicemotion的原因 允许摇一摇代码 具体原因 如果你只是想实现摇一摇,可以直接点击目录到你对应想找的地方~ 最近公司年会需要 ...

  9. 调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配...

    VS10下调用dll,代码如下: // C++接口声明 void test(char *str);// 接口声明 [DllImport("datalib.dll", EntryPo ...

最新文章

  1. yii2使用select2
  2. Python视频编辑库:MoviePy
  3. FPGA内部硬件结构简介
  4. VSTO之旅系列(五):创建Outlook解决方案
  5. python 设计模式 观察者_【python】设计模式之观察者模式
  6. windows 如何查看文件夹所使用的图标
  7. 信息学奥赛一本通 1296:开餐馆(evd)
  8. YOLO系列目标检测数据集大全
  9. 贴图平移凹凸贴图偏移
  10. python模拟手机按键_Appium+Python-模拟手机按键操作
  11. 26岁那年,我创业了
  12. 百度天气预报API接口的一个坑
  13. bzoj 4763: 雪辉
  14. python获取登录后的cookie_python爬虫使用cookie登录详解
  15. 用Python爬取了上万部电影的排名,周末周末好带女神一起去
  16. iPhone 13如何显示电量百分比?详细教程
  17. php文件怎么打开? 教你用什么软件打开php文件
  18. NLP-D62-nlp比赛D31刷题D15
  19. 情态动词学习笔记(1) 表推测
  20. mysql 安装启动服务器一直失败_mysql安装后服务器启动失败的几种解决办法

热门文章

  1. 酷狗音乐的动效界面(移动端)
  2. 中国移动应该果断应对资费之战
  3. POJ Radar Installation 1328(雷达)贪心算法
  4. python怎么去掉视频字幕_利用Python实现字幕挂载(把字幕文件与视频合并)思路详解...
  5. 【Neo4j】Neo4j安装教程/Neo4j中文版安装教程(极简)
  6. xctf攻防世界 CRYPTO高手进阶区 shanghai
  7. css字符串匹配高亮,使用正则表达式的格式化与高亮显示json字符串
  8. 海量数据分析处理入门
  9. 聊聊手机建站软件有哪些?
  10. bootstrapTable行内编辑----X-editable组件