在运行时创建面板的问题 [英] Problem creating panels at runtime

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

问题描述

 

任何人都可以帮忙吗?



我有一个小应用程序创建在运行时有许多面板,每个面板都需要一个标签,里面有一些线条。面板的数量简单地用在文本框中输入的整数来描述,我正在使用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出现故障 [ ^ ],

如何停靠按钮,以便它可以调整表格 [ ^ ]。



-SA


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 a using 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 the while loop into that, replacing the mp with e.Graphics and you should be fine.


The whole idea to create the instance of System.Drawing.Graphics is wrong. You need to do all rendering (some exclusions apply) in the handler of the Paint event or in the overridden virtual method OnPaint. 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屋!

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