Click here to Skip to main content
15,881,631 members
Please Sign up or sign in to vote.
3.50/5 (2 votes)
See more:

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:

C#
    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]
Posted
Updated 10-Feb-13 0:38am
v2

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:
C#
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.
 
Share this answer
 
Comments
Joezer BH 10-Feb-13 7:06am    
*****
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
 
Share this answer
 
v2
Comments
Wilsoni 15-Feb-13 13:28pm    
Thank you both very much for your help, it took me a while to understand what I should have been doing but I did get there in the end. The biggest problem was the size of the label I was trying to create, I obviously copied and pasted from the panel size and couldn't understand why my lines were disappearing; Just looked at it for the 100th time tonight and realised what I'd done.

Now everything works just as planned.

Best Regards
Ivan
Sergey Alexandrovich Kryukov 15-Feb-13 13:36pm    
Copy and past don't help much :-). I don't know your exact problem, but also take a look at my updated answer, after [EDIT].
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900