【WPF.NET开发】​优化性能:布局和设计

本文内容

WPF 应用程序的设计可能会在计算布局和验证对象引用时产生不必要的开销,从而影响性能。 对象的构造会影响应用程序的性能特征,在运行时更是如此。本主题提供这些方面的性能改进建议。

Layout

“布局过程”一词描述了测量和排列 Panel(派生对象的子级集合)成员的过程,然后在屏幕中绘制它们。 布局处理过程是一个数学密集型过程,即:集合中的子级数目越多,所需的计算量就越大。 例如,每当集合中的子 UIElement 对象改变其位置时,它有可能触发布局系统的一个新的过程。 由于对象特征与布局行为之间的关系非常紧密,因此有必要了解可以调用布局系统的事件类型。 应用程序将尽可能减少不必要的布局处理过程调用,从而改善性能。

布局系统对集合中的每个子成员都完成两个处理过程:测量处理过程和排列处理过程。 每个子对象提供其自身对 Measure 和 Arrange 方法的重写实现,从而提供其自身特定的布局行为。 简单地说,布局是一个递归系统,实现在屏幕上对元素进行大小调整、定位和绘制。

  • 子 UIElement 对象通过首先测量其核心属性来开始布局过程。

  • 与大小(如 Width、Height 和 Margin)相关的对象的 FrameworkElement 属性将进行计算。

  • Panel(应用特定逻辑),例如 DockPanel 的 Dock 属性,或 StackPanel 的 Orientation 属性。

  • 在测量所有的子对象后,将排列或定位内容。

  • 将子对象集合绘制到屏幕上。

如果发生下列任一操作,将再次调用布局处理过程:

  • 向集合中添加了一个子对象。

  • LayoutTransform 将应用于子对象。

  • UpdateLayout 方法用于调用子对象。

  • 使用影响测量或排列过程的元数据进行标记的依赖属性的值发生更改时。

1、尽可能使用最高效的面板

布局过程的复杂性直接取决于 Panel(使用的派生元素)的布局行为。 例如,Grid 或 StackPanel 控件提供比 Canvas 控件更多的功能。 功能大幅度改进的代价是性能成本的大幅度提高。 但是,如果不需要 Grid 控件提供的功能,则应使用成本较低的其他控件,如 Canvas 或自定义面板。

2、更新而不替换 RenderTransform

可以更新 Transform,而不是用 RenderTransform 属性的值加以替代。 在涉及动画的方案中,尤其是这样。 通过更新现有的 Transform,可以避免启动不必要的布局计算。

3、从上到下生成树

在逻辑树中添加或删除节点时,会在该节点的父级及其所有子级上引起属性失效。 因此,应始终遵循从上到下的构造模式,以避免由于在经过验证的节点中出现不必要的失效而付出代价。 下表显示了自上而下构建树与自下而上构建树的执行速度差异,其中树有 150 级深,并且每一级都有单一的 TextBlock 和 DockPanel。

Action构建树(以毫秒为单位)呈现 - 包括生成树(以毫秒为单位)
从下到上366454
自上而下1196

以下代码示例演示如何从上到下创建树。

private void OnBuildTreeTopDown(object sender, RoutedEventArgs e)
{TextBlock textBlock = new TextBlock();textBlock.Text = "Default";DockPanel parentPanel = new DockPanel();DockPanel childPanel;myCanvas.Children.Add(parentPanel);myCanvas.Children.Add(textBlock);for (int i = 0; i < 150; i++){textBlock = new TextBlock();textBlock.Text = "Default";parentPanel.Children.Add(textBlock);childPanel = new DockPanel();parentPanel.Children.Add(childPanel);parentPanel = childPanel;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue之在iframe标签里刷新外部页面

Vue之在iframe标签里刷新外部页面 在一个 <iframe> 中刷新外部页面可以通过以下几种方式实现&#xff1a; 1. 使用 window.top.location.reload() 你可以在 <iframe> 中通过 window.top 访问最顶层的 window 对象&#xff0c;然后调用其 location.reload() 方法来…

PL/SQL plsql Developer 14最新版注册码 (亲测可用)

plsql14 注册激活&#xff0c;亲测有效 product code: ke4tv8t5jtxz493kl8s2nn3t6xgngcmgf3 serial Number: 264452 password: xs374ca 激活成功

超大规模数据场景的问题(算法村第十五关黄金挑战)

对20GB文件进行排序 假设你有一个20GB的文件&#xff0c;每行一个字符串&#xff0c;请说明如何对这个文件进行排序&#xff1f; 这里给出大小是20GB,其实面试官就在暗示你不要将所有的文件都装入到内存里&#xff0c;因此我们只能将文件划分成一些块&#xff0c;每块大小是 x …

常用程序模式-LifeCycle模式

常用程序模式-LifeCycle模式 场景 当我们要监控一个组件的生命周期的时候&#xff0c;比如&#xff0c;启动时&#xff0c;启动后&#xff0c;关闭前&#xff0c;关闭后 实现 LifeCycleModule public interface LifeCycleModule {/*** 获取当前状态* return*/LifeCycle.St…

spring-web搭建

目录 1&#xff1a;spring-web是什么原理以及组成 2&#xff1a;spring-web的搭建&#xff08;以普通tomcat服务器做基础&#xff09; 1->环境&#xff08;自己去建一个普通web项目&#xff09; 2->WEB-INF的web.xml配置&#xff08;程序入口&#xff09; 3->comm…

Qt6入门教程 14:QToolButton

目录 一.简介 二.常用接口 1.void setMenu(QMenu * menu) 2.void setPopupMode(ToolButtonPopupMode mode) 3.void setToolButtonStyle(Qt::ToolButtonStyle style) 4.void setArrowType(Qt::ArrowType type) 5.void setDefaultAction(QAction * action) 三.实战演练 1…

k8s从私有库harbor中拉取镜像

一、前言 Docker镜像是构建应用程序的基础。然而&#xff0c;许多组织和开发团队希望保留他们的Docker镜像在私有仓库中&#xff0c;并从中拉取镜像&#xff0c;而不是从公共Docker Hub中下载。这样做的原因有很多&#xff0c;包括&#xff1a; 1. 安全性&#xff1a;私有仓库可…

C++ //练习 3.13 下列的vector对象各包含多少个元素?这些元素的值分别是多少?

C Primer&#xff08;第5版&#xff09; 练习 3.13 练习 3.13 下列的vector对象各包含多少个元素&#xff1f;这些元素的值分别是多少&#xff1f; ( a ) vector<int> v1; ( b ) vector<int> v2(10); ( c ) vector<int> v3(10, 42); ( d ) vector<in…

通过MediaStore查询image,video,arm,pdf等等文件数据

需要直接查询系统库来获取手机上的全部文件信息&#xff0c;如&#xff1a;图片&#xff0c;视频&#xff0c;音频&#xff0c;pdf文件等等。 直接上代码&#xff0c;获取文件的方法&#xff1a; SuppressLint("Range") public ArrayList<DataBean> getFiles(…

collection、ofType、select的联合用法(Mybatis实现树状结构查询)

需求 得到树结构数据也可以用lambda表达式也行&#xff0c;也可以直接循环递归也行&#xff0c;本文采用的是直接在Mybatis层得到结果&#xff0c;各有各的优势。 代码 1、实体类 Data public class CourseChapterVO implements Serializable {private static final long s…

Java 字符串 07 练习-手机号屏蔽、身份证号信息查看,游戏骂人敏感词替换

注意点&#xff1a;只有返回值才是被截取的小串&#xff0c;所以需要有一个变量去承接它&#xff1b; 自己写的代码&#xff1a; import java.util.Scanner; public class practice {public static void main(String[] args) {Scanner input new Scanner(System.in);String …

Zookeeper分布式命名服务实战

目录 分布式命名服务 分布式API目录 分布式节点的命名 分布式的ID生成器 分布式的ID生成器方案&#xff1a; 基于Zookeeper实现分布式ID生成器 基于Zookeeper实现SnowFlakeID算法 分布式命名服务 命名服务是为系统中的资源提供标识能力。ZooKeeper的命名服务主要是利用Z…

ThreadLocal作用实例

ThreadLocal ThreadLocal表示线程的“局部变量”&#xff0c;它确保每个线程的ThreadLocal变量都是各自独立的&#xff0c;它提供了一种方法来创建只能被当前线程访问的变量。这意味着如果有两个不同的线程访问同一个ThreadLocal变量&#xff0c;那么这两个线程将不能看到彼此…

【issue-halcon例程学习】lines_gauss.hdev

例程功能 代码如下 dev_close_window () read_image (Angio, angio-part) get_image_size (Angio, Width, Height) dev_open_window (0, 0, 3 * Width / 2, 3 * Height / 2, black, WindowID) dev_display (Angio) dev_set_color (blue) MaxLineWidth : 8 Contrast : 12 calc…

Java中的线程安全

关于多线程并发环境下&#xff0c;数据的安全问题。 1.为什么这个是重点&#xff1f; 以后在开发中&#xff0c;我们的项目都是运行在服务器当中&#xff0c;而服务器已经将线程的定义&#xff0c;线程对象的创建&#xff0c;线程的启动等&#xff0c;都已经实现完了。这些代码…

QT自制软键盘 最完美、最简单、支持中文输入(二)

目录 一、前言 二、本自制虚拟键盘特点 三、中文输入原理 四、组合键输入 五、键盘事件模拟 六、界面 七、代码 7.1 frmKeyBoard 头文件代码 7.2 frmKeyBoard 源文件代码 八、使用示例 九、效果 十、结语 一、前言 由于系统自带虚拟键盘不一定好用&#xff0c;也不一…

【python】合理使用copy与deepcopy

合理使用**copy**与**deepcopy**对于dict和list等数据结构的对象&#xff0c;直接赋值使用的是引用的方式。而有些情况下需要复制整个对象&#xff0c;这时可以使用copy包里的copy和deepcopy&#xff0c;这两个函数的不同之处在于后者是递归复制的。效率也不一样&#xff1a;&a…

动态设置小程序IOS底部小黑条

创建setIOSAreaMixin.js文件 import {mapState,mapMutations } from vuexexport default {computed: {...mapState("ios_area", ["globalAreaClass", isSafeAreaCalculated])},mounted() {if (!this.isSafeAreaCalculated) {this.calculateSafeAreaClass(…

牛客网-----------[NOIP2006]数列

题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列&#xff0c;例如&#xff0c;当k3时&#xff0c;这个序列是&#xff1a; 1&#xff0c;3&#xff0c;4&#xff0c;9&#xff0c;10&#xff0c;12&#xff0c;13&…

2024年重庆市公务员考试报名明天开始,招聘4530人!

2024年重庆公务员招录公告已出&#xff0c;招聘人数&#xff1a;4530人 ✅重庆市考重要时间节点 报名时间&#xff1a;2月1日9:00-2月6日9:00 缴费时间&#xff1a;2月8日 笔试时间&#xff1a;3月16日-17日 笔试查成绩时间&#xff1a;4月15日 面试时间&#xff1a;4月27日-2…