Link to home
Start Free TrialLog in
Avatar of int200
int200

asked on

GDI+ : Trying to use Invalidate() to erase several line segments before writing new line segments.

I have an x,y coordinate system where I draw the x axis and y axis in my Form1_Paint method.  Another method is setup called PainMe() that is responsible for drawing the line segments.  I have a button that uses a for loop to simply send the x and y parameters for each line segment to PaintMe() however I have not been able to successfully use Invalidate() to erase the lines so I can write new line segments.  Here is the following code:

/********************************
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
      this.Text="Demo";
      Graphics g = e.Graphics;
      Font vertFont = new Font("Verdana", 10, FontStyle.Bold);
      Font horzFont = new Font("Verdana", 10, FontStyle.Bold);
      SolidBrush vertBrush = new SolidBrush(Color.Black);
      SolidBrush horzBrush = new SolidBrush(Color.Blue);
      Pen blackPen = new Pen(Color.Green, 2);
      Pen bluePen = new Pen(Color.Green, 2);
      // Drawing a vertical and a horizontal line
      g.DrawLine(blackPen,this.Width/2, this.Height/2,this.Width/2, this.Height/2-this.Height/2);
      g.DrawLine(blackPen,this.Width/2, this.Height/2,this.Width/2,this.Height/2+this.Height/2);
      g.DrawLine(bluePen,this.Width/2,this.Height/2,this.Width/2+this.Width/2,this.Height/2);
      g.DrawLine(bluePen,this.Width/2,this.Height/2,this.Width/2- this.Width/2,this.Height/2);
          
      // Dispose
      vertBrush.Dispose();
      horzBrush.Dispose();
      blackPen.Dispose();
      bluePen.Dispose();
      OriginX = this.Width/2;
      OriginY = this.Height/2;
}
      private void PaintMe( Graphics g, int L1eX, int L1eY, int L2eX, int L2eY, int L3eX, int L3eY, int L4eX, int L4eY )
{
      Pen L1Pen = new Pen(Color.Red,2);
      Point L1Start = new Point(OriginX, OriginY);
      Point L1End = new Point(L1eX, L1eY);
      Pen ellipse1Pen = new Pen(Color.Red);
      
      Pen L2Pen = new Pen(Color.Blue,2);
      Point L2Start = new Point(L1eX, L1eY);
      Point L2End = new Point(L2eX, L2eY);
      Pen ellipse2Pen = new Pen(Color.Blue);
      Pen L3Pen = new Pen(Color.Orange,2);
      Point L3Start = new Point(L2eX, L2eY);
      Point L3End = new Point(L3eX, L3eY);
      Pen ellipse3Pen = new Pen(Color.Orange);
      Pen L4Pen = new Pen(Color.Black,2);
      Point L4Start = new Point(L3eX, L3eY);
      Point L4End = new Point(L4eX, L4eY);
      Pen ellipse4Pen = new Pen(Color.Black);
      g.DrawLine(L1Pen, L1Start, L1End);
      g.DrawEllipse(ellipse1Pen, L1eX-2, L1eY-2, 4, 4);
      g.DrawLine(L2Pen, L2Start, L2End);
      g.DrawEllipse(ellipse2Pen, L2eX-2, L2eY-2, 4, 4);
      g.DrawLine(L3Pen, L3Start, L3End);
      g.DrawEllipse(ellipse3Pen, L3eX-2, L3eY-2, 4, 4);
      g.DrawLine(L4Pen, L4Start, L4End);
      g.DrawEllipse(ellipse4Pen,L4eX-2, L4eY-2, 4, 4);
            
}


private void button2_Click(object sender, System.EventArgs e)
{
      System.Windows.Forms.Button b = (System.Windows.Forms.Button) sender;
      
      for(int i = 1; i <= 10; i++)
      {
                      this.Invalidate(this.ClientRectangle);
            PaintMe(b.Parent.CreateGraphics(),600+i, 400+i, 200+i, 200+i, 300+i, 300+i, 400+i, 400+i);
      }
}

**************************/

When the above is executed, Invalidate() does not erase the line segments before calling PainMe().

Avatar of AlexFM
AlexFM

I tried to reproduce your problem and got another effect: lines appear for a short time and erased. Possibly this depends on the form style.

However, your approach is wrong because all drawing code should be in Form1_Paint function or called from it. What do you try to do? Animation? Do you want to see all lines at the same time or only last line?
Invalidate will cause the following:
-After a short time of delay WindowUpdate is called
-The specified region is erased
-The paint handler is called (i guess it's "Form1_Paint")

Note the painting outside of the paint event (such as on button click) should be consistent with the painting in the OnPaint event handler!
There are two methods to achieve this:
- Either paint only in OnPaint. Set private variables to control what is painted in the next OnPaint event. You can force OnPaint to be called using Invalidate, Update (calles OnPaint for regions which are marked as invalid before), Refresh (calls Invalidate and Update).
- Or you also set private variables that control what is painted in the next paint event but instead of forcing a paint event you paint the same outside of the paint event. Note: If you paint something different it will be lost when you drag a window over your form.
Avatar of int200

ASKER

I just got back from a trip and apologize for not responding to your answers before this.  I just raised the points since I'm really looking for the 'correct' way to do what I submitted above.  I simply want to erase what was drawn and draw the new line segments.

For example, I start with 4 line segments the first connected at the origin and the rest connected to each other. I would like to either programmatically or via a button click erase the line segments that are drawn and then draw new line segments on the form.  
You didn't answer to our questions. All drawing code should be in Form1_Paint function (ot called from it). Why do you draw outside of Paint function?
Avatar of int200

ASKER

If possible, I try to write my code as modular as possible using component oriented programming practices.  In this case I am trying to write code that controls the rendering of the line segments more modular. I am writing an application to model real time data (around 10Hz to 25Hz) and need control of when I erase and redraw different line segments.  If you could show me how to get this sort of control from the Form1_Paint method it would be very helpful.
ASKER CERTIFIED SOLUTION
Avatar of ptmcomp
ptmcomp
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial