简体   繁体   English

加载具有200多个控件的Windows窗体

[英]Loading Windows form with over 200 controls

My form has over 200 control(s)! 我的表单有200多个控件! It takes about 7 seconds to load the form and bind the controls. 加载表单并绑定控件大约需要7秒钟。

I've traced the application with some performance profilers , but I didn't find anything with HOT flag except the constructor's of form. 我已经使用一些性能分析器跟踪了该应用程序,但是除了构造函数的形式外,我没有找到任何带有HOT标志的东西。

I would like to know that is it possible to call InitializeComponent method with sth like backgroundWorker (multithreading) !? 我想知道是否可以像backgroundWorker(multithreading)一样调用InitializeComponent方法!

No, threading will not help you. 不,线程化对您没有帮助。 The controls need to get created on the UI thread for the application to work at all. 需要在UI线程上创建控件,以使应用程序完全起作用。

The only reasonable way would be to look into whether you really need to create all 200 controls when the form is created, or if you can perhaps have them load "on demand". 唯一合理的方法是调查创建表单时是否真的需要创建所有 200个控件,或者是否可以“按需”加载它们。

Without knowing your application it's impossible to give more concrete guidance, but perhaps you have a situation where not all controls are in use at the same time, but rather that there is some sort of paging. 在不了解您的应用程序的情况下,不可能给出更具体的指导,但是也许您遇到的情况是并非同时使用所有控件,而是存在某种分页。 If that is the case, each "page" could perhaps be made into a user control, so that you can load and unload pages as they are needed. 如果是这种情况,则可以将每个“页面”设置为一个用户控件,以便您可以根据需要加载和卸载页面。

A better idea would be to split your UI up using a TabControl. 更好的主意是使用TabControl拆分UI。 It has lazy loading built in. 它内置了延迟加载。

Per MSDN : 每个MSDN

Controls contained in a TabPage are not created until the tab page is shown, and any data bindings in these controls are not activated until the tab page is shown. 在显示标签页之前,不会创建TabPage中包含的控件,并且在显示标签页之前,不会激活这些控件中的任何数据绑定。

And that design is directly aimed at your problem. 该设计直接针对您的问题。

Performance isn't your only problem. 性能不是您唯一的问题。 There are OS limits on the number of handles a process can own, and there are limits on the nested control layout WinForms will perform. 操作系统对进程可以拥有的句柄数量有限制,而WinForms将执行的嵌套控件布局也有限制。 If you have 200+ Windows Forms controls on a single window, I'm betting you're going to run into these and other limits. 如果您在一个窗口上有200多个Windows窗体控件,那么我敢打赌,您将遇到这些限制和其他限制。

I recommend changing your Form so that there are fewer controls: paging, virtualization, lazy loading are some techniques you can use to improve your UI and your performance. 我建议更改窗体,以便减少控件:分页,虚拟化,延迟加载是可以用来改善UI和性能的一些技术。

Things to try that others haven't mentioned: 别人没有提到的尝试方法:

  • Take the [DebuggerStepThru] option off of InitializeComponent, then you may see which items are taking long more easily (w/ profiler or just randomly hitting 'pause' in the IDE during load 20x and remembering where it stops most). 取消使用InitializeComponent的[DebuggerStepThru]选项,然后您可能会看到哪些项目花费的时间更长(使用Profiler,或者在加载20倍期间在IDE中随机击中“暂停”,并记住停在哪里)。
  • Convert to WPF if your boss will let you. 如果老板允许您转换为WPF。
  • Take the forms InitializeComponent's items, outof initialize component and on clipboard. 采取初始化组件之外的形式和剪贴板上的InitializeComponent项目形式。 Add a timer w/ 20MS ticks. 添加带有20MS刻度的计时器。 On tick, increment a counter. 勾选时,增加一个计数器。 Add one control per tick, by splitting your initializecomponent code into a 200-case select statement. 通过将initializecomponent代码拆分为200个大小写的select语句,每滴答添加一个控件。 At 201 stop the timer. 在201处停止计时器。 That way the user can start working before all the controls are added. 这样,用户可以在添加所有控件之前开始工作。 You will have to rearrange the controls.add so they show up. 您将不得不重新排列controls.add,以便它们出现。 You will have to show the important controls first. 您将必须首先显示重要的控件。 You will not be able to modify your form in the designer. 您将无法在设计器中修改表单。 Lastely, I pity the foo who thinks this bullet point is anything but a joke. 最后,我可怜那个认为这不是笑话的傻子。

I believe NGen -ing your application can help the performance a lot. 我相信NGen -ing您的应用程序可以极大地提高性能。 Most of those controls (some of them possibly custom in your application) need to be NGen-ed and that usually takes a long time, as going back to the same form is always much faster. 这些控件中的大多数(其中一些控件可能在您的应用程序中自定义)需要NGen编辑,并且通常需要很长时间,因为返回相同的格式总是更快。

While I might agree with Judah, I have seen plenty of forms in an MDI WinForms app that far exceeded 200 total controls logically contained in a form, and the form needed every one of them to do its job. 虽然我可能会同意犹大,但我在MDI WinForms应用程序中看到了很多表格,该表格逻辑上包含了200多个控件,而每个窗体都需要它才能完成工作。 An invoice entry window for instance would have a set of controls for a header, then a set of user controls that each mapped to an invoice line and had fields for SKU, description, quantity, unit price, extended price, unit tax, etc. Such a window's control count depends on the number of invoice lines, and a large order can generate an invoice requiring thousands of controls to be bound and rendered on a single screen if done naively. 例如,发票输入窗口将具有一组标题控件,然后是一组用户控件,每个控件都映射到发票行,并且具有SKU,说明,数量,单价,扩展价格,单价税等字段。这样的窗口的控件数量取决于发票行的数量,并且如果天真地完成,大订单会生成需要将数千个控件绑定并呈现在单个屏幕上的发票。 Add in further per-line detail for shipping instructions, tax information, backorder status etc. and attempting to pre-load and render every control on window load would crash the application. 在每行中添加更多详细信息,以获取运输说明,税收信息,缺货状态等,并尝试在窗口加载时预加载和呈现每个控件会使应用程序崩溃。

7 seconds seems excessive, though. 不过7秒似乎过长。 I agree with Frederik; 我同意弗雷德里克; the first step is to look and see if all 200 controls have to be rendered in order to show a single screen's worth of information. 第一步是查看是否必须渲染所有200个控件才能显示单个屏幕的信息。 Using tab controls, with event handlers for tab changes that "lazy-load" the information and controls shown on each tab, is a good first step. 使用选项卡控件以及用于选项卡更改的事件处理程序可以“延迟加载”每个选项卡上显示的信息和控件,是一个很好的第一步。 If you show lines of repetitive child information (like invoice lines on the invoice) you can save time by loading a finite page of information at a time; 如果您显示重复的子信息行(如发票上的发票行),则可以一次加载有限的信息页面,从而节省时间。 loading 10 lines is far cheaper than loading 100, and while there is some overhead in talking to a DB and dynamically loading controls that will be repeated more often this way, it will seem trivial compared to waiting several seconds just to see ANYTHING load on the window. 加载10行要比加载100行便宜得多,虽然与数据库对话和动态加载控件会有些开销,这种方式将以这种方式更频繁地重复执行,但与等待几秒钟只是为了看到加载任何内容相比,这似乎微不足道。窗口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM