问题描述
我有一个以前是树视图控件的菜单,但现在我想让每个项目更直观一些,并为树中的每个对象添加更多信息.
I have a menu that used to be a treeview control but now I want to make each item a bit more visual and add some more information to each object in the tree.
我的第一个意图是制作一个代表项目的用户控件,并在运行时将它们添加到面板中.这是一个好的方法吗?有时可能有超过一百个项目.我知道理论上你可以在表单上拥有的控件数量是最大的,但这不是我主要关心的问题.我关心的主要是性能.
My first intention was to make a user control that represents an item and add them to a panel at runtime. Is this a good aproach? There could sometimes be over one hundred items. I know that there is a maximum number of controls you can theoretically hav on a form, but that is not my main concern. My concern is mainly about performance.
我正在考虑的另一种方法是制作一个列表框并在 onPaint 方法中做一些额外的事情.但这似乎有点不稳定,而且维护起来有点过于复杂.
Another aproach I was thinking about was to make a listbox and do the extra stuff in the onPaint method. But that seems a bit unstable and a bit too complex to maintain.
有什么想法吗?
我已经通过向面板 att form_Load 添加 200 个用户控件来测试用户控件方法并且实际添加需要相当长的时间,但除此之外似乎没有任何性能问题.滚动效果很好,我已经让每个用户控件都可以折叠,并且该功能不会以任何方式滞后,即使面板中有大约 100 个上方和 100 个下方.
I've tested the usercontrol-approach by adding 200 usercontrols to the panel att form_Load and it takes a fair amount of time for the actual adding but there doesn't seem to be any performance issues aother than that. Scrolling works fine and I've made each usercontrol collapsable and that functionallity doesn't lag in any way, even when there are about a hundred above and a hundred under it in the panel.
但仍然……我在这里完全正常吗?
But still ... Am I totally of track here?
推荐答案
UserControl 是非常重"的动物,就像 System.Windows.Forms.Control 的任何实例一样,因为每个实例都包装了一个实际的底层原生 Win32 窗口.每个窗口都需要由操作系统管理、命中测试、发送绘制消息等.
UserControls are very "heavy" animals, as is any instance of System.Windows.Forms.Control, since each one wraps an actual underlying native Win32 Window. Every Window needs to be managed by the OS, hit-tested, sent paint messages, etc.
Windows 中这种情况的传统解决方案是虚拟化"控件.与其创建 200 个用户控件,不如维护一个由 200 个对象"组成的数组,代表每个项目.创建一个代表整个菜单的大"控件,为其添加一个 ScrollBar,并覆盖 OnPaint,仅绘制可见项.
The traditional solution for this scenario in Windows is to "virtualize" the control. Instead of creating 200 UserControls, maintain an array of 200 "objects" representing each item. Create one "big" control that represents the entire menu, add a ScrollBar to it, and override OnPaint, drawing only the visible items.
这就是像 ListBox 和 TreeView 这样的老式原生控件所做的.
This is what the old-school native controls like ListBox and TreeView do.
现在,我相信 Windows 可以在这方面为您提供一些帮助,具体取决于您需要获得的花哨程度.您要查找的关键字是所有者绘制".来自另一个答案:
Now I believe Windows can help you out a bit here, depending on how fancy you need to get. The keyword you're looking for is "owner-drawn". Cribbing from another answer:
子类列表框.在 ctor 中,将绘制模式设置为 OwnerDrawVariable 并覆盖 OnDrawItem 和 OnMeasureItem.
Subclass ListBox. In the ctor, set the draw mode to OwnerDrawVariable and override OnDrawItem and OnMeasureItem.
这样,本机控件将处理所有必要的滚动和数学运算,以确定您在列表中的位置以及开始绘制的位置.
This way, the native controls will handle all the scrolling and math necessary to figure out where you're at in the list and where to start painting.
这篇关于用户控制实例数量的上限(合理)限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!