专栏首页葡萄城控件技术团队Spread for Windows Forms高级主题(8)---通过暂停布局提高性能

Spread for Windows Forms高级主题(8)---通过暂停布局提高性能

一种改善控件性能的方法是,当需要对许多单元格进行变动时,可以先保持或挂起重画,直到所有的变动都完成时再进行。通过在对单元格修改和重算时保持重画(挂起布局),然后再恢复布局并重画所有单元格控件能够节省很多时间,并且仍然能为用户展现一个全新的界面。

布局对象

布局是一个对象,它保存了计算后的值(像单元格的宽度和高度,合并,以及视图),用来绘制控件的当前状态。这些值可能包括到底有多少视图,每一个视图左上方的单元格是什么,每一行及每一列有多大以及每一个视图有多少单元格是当前可见的,等等。使用布局对象的目的是,通过保存绘制控件过程所使用已计算好的布局值,每次控件重画时重新使用它们而不是每次都进行重算,来优化控件的绘制。当跟踪到一个需要重新生成布局对象的改变发生时,绘制代码就会丢弃现有的布局对象,并计算出一个新的对象。布局对象不属于公共API,但是它们缓存了绘制表单所需的所有信息,像列宽,行高,单元格合并,单元格溢出以及总是可见的长方形单元格标注(Cell.NoteStyle = NoteStyle.StickyNote)。

暂停布局逻辑

为了改善性能,你可以暂停布局,这样可以暂停布局对象的更新,因此控件不会在重画的计算上花费时间,直到恢复布局。两个方法可以完成这些操作,FpSpread类中的SuspendLayout 和ResumeLayout方法。一定要在一个特定操作的范围内同时使用这两个方法,否则暂停布局后就会出现问题,不能恢复。

当对表单进行修改时,SuspendLayout 方法能够阻止控件重新计算列、行和单元格的布局。如果你在一个代码块中对表单做了大量的变动,使用SuspendLayout方法可以避免控件在每一次变动发生时对布局对象所做的多余的中间计算,在所有变动完成之后使用ResumeLayout(true)方法重新计算布局对象。这样可以极大的提高控件的性能;另外基于表单所需要的特性,还有许多其他方法可以提高控件的性能。

System.DateTime st = System.DateTime.Now;
FpSpread1.SuspendLayout();
FpSpread1.Sheets(0).ActiveSkin = FarPoint.Win.Spread.SheetSkin.Load("d:\\temp\\skin.skn");
FpSpread1.ResumeLayout();
MsgBox("Duration (ticks)="& System.DateTime.Now.Ticks - st.Ticks)
privatevoid PerformInitialSetup(){
// (0) used for property labels._propertyLabelOrdinal =0;
// Set up the spread
spread.SuspendLayout();
SheetView sheet = spread.ActiveSheet;
sheet.Models.ColumnHeaderData =new HeaderDataModel(spread, _orientation);
sheet.Models.Style =new SheetStyleModel(_orientation);
spread.NamedStyles = _config.Styles.NamedStyles;
// Insert initial data
sheet.Columns.Count =2;
foreach (Block block in _config.Blocks)
{
// Insert any leading blank rows
if (block.SpaceBefore >0) sheet.Rows.Add(sheet.Rows.Count, block.SpaceBefore);
if (block.DealProperties !=null)
{
int rowIndex = sheet.Rows.Count;
sheet.Rows.Add(rowIndex, block.DealProperties.Count);
foreach (DealProperty property in block.DealProperties) {
sheet.Cells[rowIndex, _propertyLabelOrdinal].Value = property;
sheet.Rows[rowIndex].StyleName = block.StyleName;
rowIndex++;
  }
}
// Insert any trailing blank rows
if (block.SpaceAfter >0) sheet.Rows.Add(sheet.Rows.Count, block.SpaceAfter);
}
// Set initial styles
sheet.Columns[_propertyLabelOrdinal].StyleName ="dealPropertyLabels";
spread.ResumeLayout();
}

暂停通知

当布局被暂停后,如果没有在同一个代码块中有相应的恢复方法就会出现异常,控件会显示一个通知“布局处于暂停状态”。如果控件的状态变成这样,说明布局对象包含了非法的数据(大多数情况下为错误的数值),当控件使用非法的布局数据绘制时就会导致异常发生。在绘制控件过程中,如果发生未被捕捉的异常,通知就会出现,并且在异常发生时布局也会被暂停。

这些只会在使用SuspendLayout方法暂停布局时才会发生,然后对控件状态所做的改变也会生效,控件也会以某种方式使用非法的布局对象进行再次绘制。也可能存在这样的异常,它导致上述消息的显示,但却与暂停布局无关;例如,IRenderer.PaintCell方法调用过程中由自定义单元格类型对象抛出的异常。对控件状态所做的任何修改都会触发布局的重计算,但并非所有的改动都是这样。对行或列进行重新排列时,如排序和过滤,肯定需要重计算,但设置文本只有在某些情况下才需要重计算,例如,当你将AllowCellOverflow属性打开时。即使布局被暂停,Spread控件仍然可以使用之前的正确布局信息来绘制控件;但之后Spread控件可能会产生不可预知的情况,例如,当你想要滚动页面而控件却没有反应,也没有显示异常通知。

其他改善性能的方法

如果你不使用手写便笺,那么可以将AutoUpdateNotes属性设置为false,阻止控件对必须被设置为可见或隐藏或可移动的手写便笺进行检查。如果你使用了AllowCellOverflow属性,将其关闭可以提高布局计算的性能,因为每次对单元格中的数据进行修改时,这个特性需要许多对文本宽度的计算。如果你使用了公式,在更新之前将AutoCalculation属性设置为false,然后再将其设回true,并调用Recalculate方法,这样可减少对公式的多余中间计算。

你还可以做一些其他的操作提高性能,如减小控件的大小,或减少一次性显示的列数和行数(布局对象只计算表单的可见部分),或实现你自己的表单模型对象(就像实现了ISheetDataModel接口的数据模型对象),删除不需要的功能特性(例如,当你不需要数据绑定时,就不用实现数据绑定相关的接口)。

同时使用两个方法

大概的程序结构如下:

SuspendLayout

在这里插入你的代码

ResumeLayout

这两个方法用来暂时忽略对布局所做的修改,这样可以进行许多修改操作,而不用在每次修改时进行多余的布局重计算。当布局计算被暂停时,跟踪控件修改的事件处理器不能对布局进行重计算,并且绘制代码不会访问新的布局。在使用嵌套循环修改每一个单元格时,像修改每一个单元格的值,这种情况肯定可以从先暂停布局,然后再恢复布局的方式中获益。

请记住,如果在对控件进行修改时不能从暂时停止布局中获得性能提升,就不要使用这些方法。一定要在同一个代码块中同时使用这两个方法; 否则,如果调用 SuspendLayout方法时没有在同一个代码块中相应的调用 ResumeLayout方法,控件可能无法正确的绘制。

在下面的示例代码中,我们在修改单元格的代码附近的代码块中同时使用了这两个方法。在修改单元格的颜色时,代码暂停了Spread控件的重画,并在之后恢复了重画。

fpSpread1.SuspendLayout();
fpSpread1.Sheets[0].Cells[0, 0, 499, 499].BackColor = Color.White;
fpSpread1.ResumeLayout(true);

Spread for Windows Forms 5.0 中文版下载地址

附:Spread for Windows Forms高级主题系列文章

Spread for Windows Forms高级主题(1)---底层模型

Spread for Windows Forms高级主题(2)---理解单元格类型

Spread for Windows Forms高级主题(3)---理解单元格的编辑模式

Spread for Windows Forms高级主题(4)---自定义用户交互

Spread for Windows Forms高级主题(5)---数据处理

Spread for Windows Forms高级主题(6)---数据绑定管理

Spread for Windows Forms高级主题(7)---自定义打印的外观

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ComponentOne.NET仪表板布局控件 — 实现可视化数据大屏展示

    .NET开发领域的总体趋势是互操作性,葡萄城全功能 .NET控件集 ComponentOne 在2018将延续这一趋势:无论是 .NET平台,ASP.NET C...

    葡萄城控件
  • 中国电建:ComponentOne+Spread突破行业桎梏,推动数据产业“智能化”变革

    中国电建集团北京勘测设计研究院有限公司(简称:北京院)始建于1953年,是大型综合性勘测设计研究单位,现为中国电力建设集团有限公司(世界500强企业)的全资子企...

    葡萄城控件
  • Spread for Windows Forms快速入门(10)---绑定到数据库

    下面的教程将带你创建一个工程, 并将Spread控件绑定到一个数据库。 在这个教程中,主要的步骤为: 1. 将Spread添加到一个数据绑定工程中 2. 设置数...

    葡萄城控件
  • DataWindow.Net组件示例(全部开源)

    1概述 1.1功能简介 Sybase公司的PowerBuilder开发工具,在以前VS工具没有成事以前,是相当风光的.微软都要与其合作,学习它Db方面的技术,才...

    用户1219352
  • Excel ActiveX教程(一)

            VBA真的是一个很强大的东西,当人家手工黏贴的时候,你只要编好代码,然后一劳永逸。不过最近发现ActiveX用起来好像更加方便的样子,特别是对于...

    钱塘小甲子
  • 微信公众号token验证

    本节来说一下微信公众号token验证问题,关于微信公众号token验证是微信开发前期的必要过程。主要是为了验证服务器是否属于你,也可以理解为你是否拥有使用此服务...

    小白程序猿
  • 构建布局良好的Windows程序

    工具箱→菜单和工具栏 菜单栏 MenuStrip的类型 MenuItem:菜单项 TextBox:文本框 ComboBoX:组合框 Separato:分割线 前...

    房上的猫
  • 断言和分段控制器1. 断言(Assertions)2. 分段控制器(UISegmentedControl)

    stanbai
  • iOS之分段控制器UISegmentedControl1. 分段控制器(UISegmentedControl)2. 事件监听3. 手势事件大全

    stanbai
  • OEA 中 WPF 树型表格整体重构

    为什么要重构     上两个月主要做了一件事情,那就是把 OEA 框架中的 TreeGrid 控件,从结构上重新设计,并大量重构现有代码。而花较大精力做这件事的...

    用户1172223

扫码关注云+社区

领取腾讯云代金券