循环创建控件 [英] Create controls in loop

查看:44
本文介绍了循环创建控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好.
我想通过循环创建控件,但不想将其定义为循环的每个步骤中的新控件,例如:(因为它消耗大量的内存和CPU)

Hi there.
I want to create controls through loop, but not to define it as new control on each step of loop, like: (because it consumes a lot of mem and cpu)

for (int h = 0; h < Variables.test; h++)
{
  CheckBox chk = new System.Windows.Forms.CheckBox();
  chk.AutoSize = true;
  chk.Size = new System.Drawing.Size(67, 17);
  chk.UseVisualStyleBackColor = true;
  chk.Enabled = true;
  chk.Click += new EventHandler(Main_Click);
  chk.Location = new System.Drawing.Point(45, h * 20 + 200);
  chk.Name = Variables.tblNames[h];
  chk.Text = Variables.tblNames[h];
  this.Controls.Add(chk);
  a[h] = chk;
}


tblnames是一个参数为字符串的数组< br/>
a是具有控制参数的数组

但相反,例如:


tblnames is a array with parameters as strings<br/>
a is a array with control parameters

But instead, like:

CheckBox chk = new System.Windows.Forms.CheckBox();
chk.AutoSize = true;
chk.Size = new System.Drawing.Size(67, 17);
chk.UseVisualStyleBackColor = true;
chk.Enabled = true;
chk.Click += new EventHandler(Main_Click);
for (int h = 0; h < Variables.test; h++)
{
  chk.Location = new System.Drawing.Point(45, h * 20 + 200);
  chk.Name = Variables.tblNames[h];
  chk.Text = Variables.tblNames[h];
  this.Controls.Add(chk);
  a[h] = chk;
}


但是问题是,在第二个代码中,值都相同(a = {3,3,3}而不是a = {1,2,3})

有人可以帮我找到问题所在的代码,还是有更好的主意通过循环创建控件.


BUT, the problem is that in the second code, a values are all the same (a={three,three,three} instead of a={one,two,three})

Can someone help me to find where the problem lies on the code, or is there any better idea to create controls through loop.

推荐答案

这是因为在第二个示例chk在循环之外(看,它是在其中调用构造函数的地方),因此您不使用3个(或多少个)不同的控件,而是使用相同的控件重复所有迭代.如果只调用一次CheckBox构造函数,则只有一个CheckBox,对吗?所以,难怪...

记录一下:您的第一个样本非常有意义.第二个目的是什么?
您说但不要将其定义为循环的每个步骤上的新控件"(为什么不呢?!),但这不是要定义",而是要创建.无论是否循环,创建一个实例时都只有一个实例.
This is because in second sample chk is outside the loop (look, it''s where you call a constructor), so you''re not working with 3 (or how many) different controls, but repeat all iterations with the same one. If you call a CheckBox constructor only once, there is only one CheckBox, right? so, no wonder...

For a record: your first sample make perfect sense. What would be a purpose of the second one?
You say "but not to define it as new control on each step of loop" (why not?!), but this is not to "define", this is to create. In a loop or not, you only have an instance when you create one...


SAKryukov,谢谢您的回答.在循环的每个步骤上创建控件的处理是,当我尝试添加90个具有两个复选框的groupbox时,它会变得很重并且挂起.因此,它的270个控制在一个循环中,并且大约一分钟消耗了我25%的cpu(四核).

您有更好的主意,以使其更快地实现吗?
SAKryukov, thank You for your answer. The deal with creating controls on each step of loop, is that it gets heavy and it hangs when i try to add 90 groupboxes with two checkboxes in each of it. So it''s 270 controls in one loop, and it consumes 25% of my cpu (a quad core) for about a minute.

Do you have any better idea, to make it happen faster?


对不起,我对提高可创建600个控件的应用程序的性能不感兴趣.为什么?没有人会一次查看超过十个(多达两个)的活动控件.如果您坚持使用太多控件,则必须解释其目的,因为这太过奇特了.

因此,如果您准备重新设计为更合理/更实用的方法,则可以执行以下操作:

您需要将大量控件的结构设计为一些章节",子章节" ...以某种合理深度的层次结构.每个章节都在单独的面板中,但是您永远不应创建所有666;)控件.一次只能看到一个章节,每个章节都包含有限的可观察到的可用控件数.您只需要一个面板,但是每次导航到感兴趣的章节时,控件都会被删除并重新填充(见下文).

如何导航?在您的主窗口左侧,想象一个行为类似于目录(TOC)的控件.最通用的视图将提供一个TreeView,一个简单的视图(1级层次结构)-一个列表框.在此控件上,您从一个条目导航到另一个代表一个章节的条目.设置事件处理程序OnSelectionChanged:它应清洁右侧的面板,并用新的控件集重新填充它.

在树状视图中要放置什么?

您需要用字符串表示的内容,同时项目类型应在右侧的控件集上携带数据.解决此问题的方法是使用某些覆盖了object.ToString的结构:

Sorry, I''m not interested in improving performance of application which creates 600 controls. Why? Nobody will look at more than ten (to many two tens) active controls at a time. If you insist on so many controls, you''ll have to explain the purpose, because this thing would be way too exotic.

So, if you''re ready to re-design into more reasonable/practical approach, here is what you can do:

You need to structure design of you mass of controls into some "chapters", "sub-chapters"... into some hierarchy of reasonable depth. Each chapter goes in separate panel, but you should not ever create all 666 ;) controls. Only one chapter should be visible at a time, each containing limited observable an usable number of controls. You need only one panel, but controls are removed and re-populated each time you navigate (see below) to a chapter of interest.

How to navigate? On your main window left, imagine a control that behaves like Table of Contents (TOC). Most general view would provide a TreeView, a simple one (1-level hierarchy) -- a list box. On this control, you navigate from item to item each representing a chapter. Setup event handler OnSelectionChanged: it should clean the panel on your right and repopulate it with new set of controls.

What to put in tree view?

You need something that would be represented as a string, at the same time the item type should carry data on control set on your right. The way to resolve this is some structure with overridden object.ToString:

struct ItemInfo {
    internal ItemInfo(string name /* something else ... */) { Name = name; }
    public override string ToString() {
        return Name.ToString();
    } //ToString
    string Name;
    //whatever else
    //...
} //struct ItemInfo



现在,您需要使用ItemInfo类型的项目填充TOC控件:



Now, you need to populate your TOC control with items of the type ItemInfo:

//...
string name = //...
ItemInfo info = new ItemInfo(name);
box.Items.Add(info);
//...



处理OnSelectionChanged时,您知道可以将项目的Content下放到ItemInfo.

开发诸如CreatePageControls(ref ItemInfo info)的填充过程,并从OnSelectionChanged的处理程序中调用它.

现在,由于您一次只显示几个控件,因此任何性能就足够了(在UI事件中,一毫秒不计在内).

让您从另一个角度看一下:您是否熟悉虚拟容器控件和/或控件的虚拟模式(例如网格视图或列表视图)?您可以想到我所描述的虚拟模式容器设计.或者,您可以使用由例如滚动条控制的虚拟容器提出更通用的解决方案.滚动条可以显示90万个虚拟项目,其中只有一小部分是同时存在的:只有可滚动区域可见部分中的虚拟项目,再加上这个地方的上下部分,以便更好地兑现.

怎么样?



When you handle OnSelectionChanged, you know that you can downcast you item''s Content to ItemInfo.

Develop population procedure like CreatePageControls(ref ItemInfo info) and call it from your handler of OnSelectionChanged.

Now, as you show only few controls at a time, any performance will be sufficient (on UI event, one millisecond does not count).

To give you an idea of another look at this: are you familiar with virtual container controls and/or virtual mode of controls such as grid views or list views? You can think of the design I describe as of a virtual-mode container. Alternatively, you can make more general solution using virtual container controlled by, say, a scroll bar. A scroll bar can show 900 thousands of virtual items, with only a small part of them existing physically at the same time: only those in the visible part of scrollable area plus as many down and up of this place, for better cashing.

How about that?


这篇关于循环创建控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆