在运行时创建面板的问题 [英] Problem creating panels at runtime
问题描述
任何人都可以帮忙吗?
我有一个小应用程序创建在运行时有许多面板,每个面板都需要一个标签,里面有一些线条。面板的数量简单地用在文本框中输入的整数来描述,我正在使用FOR循环来创建具有嵌套WHILE循环的控件,该循环绘制线条。
到目前为止我编写的代码创建了面板和标签,但我无法绘制线条。我已经使用断点来尝试缩小问题范围,看起来好像面板和标签在方法执行完毕之前并没有被绘制出来。
我的代码:
public void CreatePanels()
{
int PanelPosX = 50 跨度>;
int PanelPosY = 500 ;
int LabelPosX = 10 ;
int LabelPosY = 10 ;
for ( int i = 0 ; i < (Convert.ToInt32(textBox2.Text)); i ++)
{
// 创建新面板
面板pnlOverview = new Panel();
pnlOverview.Name = InspectorPanel + i.ToString();
pnlOverview.Text = Inspector Panel + i.ToString();
pnlOverview.Location = new Point(PanelPosX,PanelPosY);
pnlOverview.Size = new 大小( 974 , 136 跨度>);
pnlOverview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
Controls.Add(pnlOverview);
PanelPosY + = 170 ;
// 在面板内添加标签
Label lblInspectorName = new Label();
lblInspectorName.Name = InspectorName + i.ToString();
lblInspectorName.Text = Inspector + i.ToString();
lblInspectorName.Width = 100 ;
lblInspectorName.Height = 13 ;
lblInspectorName.Location = new Point(LabelPosX,LabelPosY);
lblInspectorName.Size = new 大小( 974 , 136 跨度>);
pnlOverview.Controls.Add(lblInspectorName);
// 在面板内画一些线
int x = 10 ;
int y = 0 ;
Pen OVTable = new 笔(Color.Black, 0 );
while (y < 5 )
{
Graphics mp = pnlOverview.CreateGraphics();
mp.DrawLine(OVTable,x, 40 ,x, 100 );
y ++;
x + = 8 ;
}
}
return ;
}
}
任何帮助将不胜感激
IW
[edit]已添加代码块 - OriginalGriff [/ edit]
它比那更基础,我很害怕。
当你创建一个图形上下文并绘制一些东西时,绘图是没有保留 - 它是暂时的,并将存活直到下一次Windows决定需要重新绘制控件。在你的方法结束后,你的方法会立即结束...:笑:
此时你绘制的线条将被删除,以便为控制器准备绘图表面以自行绘制。 />
所以,你必须做两件事:
1)首先,如果你创建一个Graphics对象,你负责处理它 - 如果没有这样做(如上面的代码中那样)将导致长期运行中的原因问题,因为图形上下文是稀缺资源,并且在垃圾收集器转向为您删除它们之前很长时间都会耗尽它们。此时你的程序会崩溃。如果您创建了稀缺资源,请使用块将其封装在中:
你应该没事。
using (Graphics mp = pnlOverview.CreateGraphics())
{
mp.DrawLine(OVTable,x, 40 ,x, 100 );
y ++;
x + = 8 ;
}
2)不要这样做 - 你需要处理面板的Paint事件并绘制线条那里。只需在构造面板时添加事件处理程序,然后将while
循环移动到该处,用<替换mp
code> e.Graphics
创建System.Drawing实例的整个想法。图形
是错误的。您需要在Paint
事件的处理程序中或在重写的虚拟方法OnPaint
。请查看我过去的答案,我在那里解释一下:
mdi子表单之间的绘制线 [ ^ ],
在面板上捕获图纸 [ ^ ],
什么样的俏皮方法是Paint? (DataGridViewImageCell.Paint(...)) [ ^ ],
如何加速我的vb.net应用程序? [ ^ ]。
< blockquote class =FQ>Wilsoni写道:最大的问题是我试图创建的标签大小。
关于大小问题,正确布局可能有所帮助请查看我过去的答案:
屏幕分辨率更改时,Zom Out出现故障 [ ^ ],
如何停靠按钮,以便它可以调整表格 [ ^ ]。
Can anybody help??
I have a small application which creates a number of panels at runtime, each panel needs a label and some lines inside it. The number of panels is depicted simply from an integer entered in a text box, and I''m using a FOR loop to create the controls with a nested WHILE loop which draws the lines.
The code I have written so far creates the panels and labels, but I can''t get the lines to draw. I''ve used a breakpoint to try and narrow down the problem and it seems as though the panels and labels aren''t actually being drawn until the method has finished executing.
My code:
public void CreatePanels()
{
int PanelPosX = 50;
int PanelPosY = 500;
int LabelPosX = 10;
int LabelPosY = 10;
for (int i = 0; i < (Convert.ToInt32(textBox2.Text)); i++)
{
// Create a new panel
Panel pnlOverview = new Panel();
pnlOverview.Name = "InspectorPanel" + i.ToString();
pnlOverview.Text = "Inspector Panel " + i.ToString();
pnlOverview.Location = new Point(PanelPosX, PanelPosY);
pnlOverview.Size = new Size(974, 136);
pnlOverview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
Controls.Add(pnlOverview);
PanelPosY += 170;
// Add a label inside the panel
Label lblInspectorName = new Label();
lblInspectorName.Name = "InspectorName" + i.ToString();
lblInspectorName.Text = " Inspector " + i.ToString();
lblInspectorName.Width = 100;
lblInspectorName.Height = 13;
lblInspectorName.Location = new Point(LabelPosX, LabelPosY);
lblInspectorName.Size = new Size(974, 136);
pnlOverview.Controls.Add(lblInspectorName);
// Draw some lines inside the panel
int x = 10;
int y = 0;
Pen OVTable = new Pen(Color.Black, 0);
while (y < 5)
{
Graphics mp = pnlOverview.CreateGraphics();
mp.DrawLine(OVTable, x, 40, x, 100);
y++;
x += 8;
}
}
return;
}
}
Any help would be much appreciated
IW
[edit]Code block added - OriginalGriff[/edit]
It''s a bit more fundamental than that, I''m afraid.
When you create a Graphics context and draw something, the drawing is not preserved - it is transitory and will survive until the next time Windows decides the control needs to be re-drawn. Which in your case will be immediately after your method ends...:laugh:
At which point the lines you have drawn will be erased to prepare the drawing surface fro the controls to drawn themselves.
So, there are two things you must do:
1) First, if you create a Graphics object you are responsible for Disposing of it - failing to do that (as in your code above) will cause cause problems in teh long run, because Graphics contexts are scarce resources and you will run out of them a long time before the Garbage Collector gets round to deleting them for you. At this point you program will crash. If you ever create a scarce resource, enclose it in ausing
block:
using (Graphics mp = pnlOverview.CreateGraphics()) { mp.DrawLine(OVTable, x, 40, x, 100); y++; x += 8; }
2) Don''t do it that way - you need to handle the Paint event for the panel and draw the lines in there. Just add the event handler when you construct the panel, and move thewhile
loop into that, replacing themp
withe.Graphics
and you should be fine.
The whole idea to create the instance ofSystem.Drawing.Graphics
is wrong. You need to do all rendering (some exclusions apply) in the handler of thePaint
event or in the overridden virtual methodOnPaint
. Please see my past answers where I explain it all:
Drawing Lines between mdi child forms[^],
capture the drawing on a panel[^],
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
How to speed up my vb.net application?[^].
[EDIT]
Wilsoni wrote:The biggest problem was the size of the label I was trying to create.
As to the problem of the size, correct layout might help. Please see my past answers:
Zom Out malfunctions when Screen resolution changes[^],
how to dock button so that it can adjust with the form[^].
—SA
这篇关于在运行时创建面板的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!