Hi, all...

I wish to call upon the DrawLinesPointF class to draw an array of points for me after I click on a button with design name button1. Upon compilation of my code, there is no error. However, when executed, and I clicked on the button, the following exception error occured:

An unhandled exception of type 'System.InvalidCastException' occurred in DrawingLines_Testing.exe

Additional information: Specified cast is not valid.

And the following line was highlighted:

DrawLinesPointF(sender, (PaintEventArgs) e);

Below is part of my code. Is there any problems with my definitions of the classes? Why do I have the problem with calling the class DrawLinesPointF? What do I have or lack?

private void DrawLinesPointF(object sender, PaintEventArgs e)
{
    // Create pen.
    Pen pen = new Pen(Color.Black, 3);
    // Create array of points that define lines to draw.
    PointF[] points =
    {
        new PointF( 10.0F,  10.0F),
        new PointF( 10.0F, 100.0F),
        new PointF(200.0F,  50.0F),
        new PointF(250.0F, 300.0F)
    };
    //Draw lines to screen.
    e.Graphics.DrawLines(pen, points);
}

private void button1_Click(object sender, System.EventArgs e)
{
    Graphics g = button1.CreateGraphics();

    // Creates a pen that draws in red.
    Pen myPen1 = new Pen(Color.Red, 3);

    g.DrawLine(myPen1, 1, 1, 200, 200);

    DrawLinesPointF(sender, (PaintEventArgs) e);
}

Dani AI

Generated

Short summary and root cause: the exception comes from trying to treat the Click handler’s EventArgs as a PaintEventArgs and from using the button as the drawing target. As pointed out, EventArgs from a Click cannot be cast to PaintEventArgs. As suggested, the drawing routine should receive the actual Graphics to draw on rather than an inappropriate event object.

Recommended (best) pattern

  • Move all drawing into the Paint handler of the control you want to paint (Form, Panel, etc.). Use the PaintEventArgs there (e.Graphics) or call a helper that accepts a Graphics parameter. From the button click simply call Invalidate() or Refresh() to request a repaint. This makes the drawing persistent (it survives minimizing, covering/uncovering) and uses the correct paint cycle.

Quick alternative (transient)

  • If you need immediate, temporary drawing (preview), obtain a Graphics from the intended control (not from the Click EventArgs), call a helper that accepts Graphics, then dispose the Graphics. This is fine for quick feedback but will be lost on the next repaint, so it’s not a substitute for proper Paint-based drawing.

Practical cautions and checklist

  • Don’t cast System.EventArgs to PaintEventArgs.
  • Either change your DrawLines method to accept a Graphics object or keep it only for use inside a Paint handler.
  • Dispose pens/brushes (use using) and enable double buffering on the control to reduce flicker for complex drawings.
    Following those steps resolves the cast error, prevents drawing on the wrong control, and makes your graphics persistent and correct.

Recommended Answers

All 7 Replies

take out that sender param in the draw line you do not need that and pass the graphics(g) not the paint event args

Sorry... I don't get you... u mean change the last line to the following?

From : DrawLinesPointF(sender, (PaintEventArgs) e);

To : DrawLinesPointF(g);

Is this what u mean?

Anyway I tried this, but upon compilation, the following error comes out.

No overload for method 'DrawLinesPointF' takes '1' arguments

Please help... Thanks...

Where to start.. your logic is wrong i suspect. Your code will draw it in the button.
First problem is your cast error you mention...
DrawLinesPointF(sender, (PaintEventArgs) e);

you are trying to cast e to PaintEventArgs but e is a SystemEventArgs which is empty so there is no way it will ever cast.

Secondly you are sending the button as the sender to your DrawLinesPointF function and in that function you get the graphics object to draw to, hence you will draw in the button and not on your form.

If you tell us what you are trying to achieve and on what then we can help, but rethink your logic first.

private void DrawLinesPointF(Graphics g)//<--change this to accept graphics not args
{
// Create pen.
Pen pen = new Pen(Color.Black, 3);
// Create array of points that define lines to draw.
PointF[] points =
{
new PointF( 10.0F, 10.0F),
new PointF( 10.0F, 100.0F),
new PointF(200.0F, 50.0F),
new PointF(250.0F, 300.0F)
};
//Draw lines to screen.
g.DrawLines(pen, points);///<- use the passed graphics to draw
}

private void button1_Click(object sender, System.EventArgs e)
{
Graphics g = button1.CreateGraphics(); //<--creates graphics to draw on button

// Creates a pen that draws in red.
Pen myPen1 = new Pen(Color.Red, 3);

g.DrawLine(myPen1, 1, 1, 200, 200);

DrawLinesPointF(g);//<--passes button graphics
}

I dont think he wants to draw to the button though, which is why i asked. hopefully he will know how to get the graphics of whatever control he wants to draw to from your code :)

oh well in that case jsut replace the "button1.CreateGraphics();"
with "Graphics g = this.CreateGraphics();"

that will draw on the form

you can draw on anything this way

Wow U All are AMAZING PPL!
Thanks a BILLiON! ^^

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.