Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Why does the Form_Paint event run continuously and only draw once ?

Why does the Form_Paint event run continuously and only draw once ?

Scheduled Pinned Locked Moved C#
questiongraphicslounge
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    User 2456424
    wrote on last edited by
    #1

    I have the following code, I put a label in Form_Paint to track the number jump, I see the label jumping continuously but e.Graphics.DrawString(...) only looks once, does anyone know why ?

    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    //progressBar1.Visible = false;
    progressBar1.Minimum = 0;
    progressBar1.Maximum = 100;

            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1\_Paint);
    
        }
        int iNum = 0;        
        private void btnDrawText\_Click(object sender, EventArgs e) //PaintEventArgs e
        {            
            progressBar1.Value = 0;
            progressBar1.Visible = true;
            this.timer1.Interval = 100;
            this.timer1.Enabled = true;            
                       
        }
        private void ShadowedTextPaint(PaintEventArgs e, int num)
        {
            using (Font font1 = new Font("Times New Roman", 250, FontStyle.Bold, GraphicsUnit.Pixel))
            {
                PointF pointF1 = new PointF(310, 270);
                e.Graphics.DrawString(num.ToString(), font1, Brushes.LightGreen, pointF1);                
                lblNum.Text = num.ToString();
            }            
            
        }
        private void Form1\_Paint(object sender, PaintEventArgs e)
        {
            ShadowedTextPaint(e, iNum);
        }
        private void timer1\_Tick(object sender, EventArgs e)
        {            
            if (progressBar1.Value < 100)
            {                
                Random rd = new Random();
                iNum = rd.Next(0, 999);                
                progressBar1.Value++;
            }
            else
            {                
                this.timer1.Enabled = false;
                progressBar1.Visible = false;                
            }
            
        }
    

    }

    D 1 Reply Last reply
    0
    • U User 2456424

      I have the following code, I put a label in Form_Paint to track the number jump, I see the label jumping continuously but e.Graphics.DrawString(...) only looks once, does anyone know why ?

      public partial class Form1 : Form
      {
      public Form1()
      {
      InitializeComponent();
      //progressBar1.Visible = false;
      progressBar1.Minimum = 0;
      progressBar1.Maximum = 100;

              this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1\_Paint);
      
          }
          int iNum = 0;        
          private void btnDrawText\_Click(object sender, EventArgs e) //PaintEventArgs e
          {            
              progressBar1.Value = 0;
              progressBar1.Visible = true;
              this.timer1.Interval = 100;
              this.timer1.Enabled = true;            
                         
          }
          private void ShadowedTextPaint(PaintEventArgs e, int num)
          {
              using (Font font1 = new Font("Times New Roman", 250, FontStyle.Bold, GraphicsUnit.Pixel))
              {
                  PointF pointF1 = new PointF(310, 270);
                  e.Graphics.DrawString(num.ToString(), font1, Brushes.LightGreen, pointF1);                
                  lblNum.Text = num.ToString();
              }            
              
          }
          private void Form1\_Paint(object sender, PaintEventArgs e)
          {
              ShadowedTextPaint(e, iNum);
          }
          private void timer1\_Tick(object sender, EventArgs e)
          {            
              if (progressBar1.Value < 100)
              {                
                  Random rd = new Random();
                  iNum = rd.Next(0, 999);                
                  progressBar1.Value++;
              }
              else
              {                
                  this.timer1.Enabled = false;
                  progressBar1.Visible = false;                
              }
              
          }
      

      }

      D Offline
      D Offline
      Dave Kreskowiak
      wrote on last edited by
      #2

      My first guess would be it's because you're setting the Text property of a Label control in your paint event, which will cause the label to Invalidate and require painting, which may be generating another WM_PAINT message for your form. Handle the paint event, but only do painting in it, not messing with other controls that have nothing to do with drawing content. Also, your in Tick event handler, the else clause of the If statement is unnecessary. The Timer control in the ToolBox does not need to be re-enabled on every tick, and the ProgressBar is always going to be visible since you never set it to not be visible. Your Random really shouldn't be recreated on every tick of the timer. You can just create a single instance as the class level and just keep using that. But, since you're not even using the random numbers you're getting, why even have it in there?

      Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
      Dave Kreskowiak

      U 1 Reply Last reply
      0
      • D Dave Kreskowiak

        My first guess would be it's because you're setting the Text property of a Label control in your paint event, which will cause the label to Invalidate and require painting, which may be generating another WM_PAINT message for your form. Handle the paint event, but only do painting in it, not messing with other controls that have nothing to do with drawing content. Also, your in Tick event handler, the else clause of the If statement is unnecessary. The Timer control in the ToolBox does not need to be re-enabled on every tick, and the ProgressBar is always going to be visible since you never set it to not be visible. Your Random really shouldn't be recreated on every tick of the timer. You can just create a single instance as the class level and just keep using that. But, since you're not even using the random numbers you're getting, why even have it in there?

        Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
        Dave Kreskowiak

        U Offline
        U Offline
        User 2456424
        wrote on last edited by
        #3

        The Label Control I put in the Form_Paint event is for me to troubleshoot it without affecting or messing up the information in the Form_Paint event or argument, I verified this with the Debug.Print debugger ("..." ); My Random function gets a random number and the Tick event determines the time to stop redrawing, the ideas you give me are incorrect. What do you think is the use of Form_Paint to draw random numbers continuously over time ?

        D 1 Reply Last reply
        0
        • U User 2456424

          The Label Control I put in the Form_Paint event is for me to troubleshoot it without affecting or messing up the information in the Form_Paint event or argument, I verified this with the Debug.Print debugger ("..." ); My Random function gets a random number and the Tick event determines the time to stop redrawing, the ideas you give me are incorrect. What do you think is the use of Form_Paint to draw random numbers continuously over time ?

          D Offline
          D Offline
          Dave Kreskowiak
          wrote on last edited by
          #4

          The Label control was a bad idea because it changes the behavior of your code. When you set the value of the Text property, the label does not get repainted at that time. It forces the label to Invalidate itself, telling Windows that it needs to repaint. Windows will get around to posting a WM_PAINT message to the applications message queue. When the UI thread finally goes back to idle, the queue will get processed and the paint message makes it way to the label control, telling it that it is now OK to paint itself. That is when the label actually changes on screen. Moving on, you never use the value of the Random so it's never being painted anywhere. Form_Paint is a bit much for this. I'd create a Control specifically for the purpose. This makes the code reusable and easily maintained. The control would have it's own Random, it's own Timer, and a couple of methods to Start and Stop it's behavior.

          Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
          Dave Kreskowiak

          U 1 Reply Last reply
          0
          • D Dave Kreskowiak

            The Label control was a bad idea because it changes the behavior of your code. When you set the value of the Text property, the label does not get repainted at that time. It forces the label to Invalidate itself, telling Windows that it needs to repaint. Windows will get around to posting a WM_PAINT message to the applications message queue. When the UI thread finally goes back to idle, the queue will get processed and the paint message makes it way to the label control, telling it that it is now OK to paint itself. That is when the label actually changes on screen. Moving on, you never use the value of the Random so it's never being painted anywhere. Form_Paint is a bit much for this. I'd create a Control specifically for the purpose. This makes the code reusable and easily maintained. The control would have it's own Random, it's own Timer, and a couple of methods to Start and Stop it's behavior.

            Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
            Dave Kreskowiak

            U Offline
            U Offline
            User 2456424
            wrote on last edited by
            #5

            I use the label control to debug the program instead of the Debug.Print("..."), I think the label control doesn't affect as you say. you say: "i never use the value of the Random so it's never being painted anywhere." What do I use to generate random numbers ? you say: "Form_Paint is a bit much for this. I'd create a Control specifically for the purpose ..." I haven't seen you create a Control specifically posted by you for everyone to see ?

            D 1 Reply Last reply
            0
            • U User 2456424

              I use the label control to debug the program instead of the Debug.Print("..."), I think the label control doesn't affect as you say. you say: "i never use the value of the Random so it's never being painted anywhere." What do I use to generate random numbers ? you say: "Form_Paint is a bit much for this. I'd create a Control specifically for the purpose ..." I haven't seen you create a Control specifically posted by you for everyone to see ?

              D Offline
              D Offline
              Dave Kreskowiak
              wrote on last edited by
              #6

              Member 2458467 wrote:

              I use the label control to debug the program instead of the Debug.Print("..."), I think the label control doesn't affect as you say.

              Actually, it does work as I say, and it WILL lie to you when you have the UI thread tied up doing other things instead of letting it process the message pump so forms and controls can repaint themselves. Don't believe me? Start a new Windows form project and drop a label and a button on the form. Double click the button to create an event handler and drop the following code into the button handler:

              for (int i = 1; i < 20000000; i++)
                  label1.Text = i.ToString();
              

              Run it and click the button. Notice the label doesn't update? Also, you can't move the form around the screen either. It's doing this because you've got the UI thread tied up doing a long-running operation. It's can't process messages, like WM_PAINT, until that operation completes.

              Member 2458467 wrote:

              you say: "i never use the value of the Random so it's never being painted anywhere." What do I use to generate random numbers ?

              You use Random to generate the values, but you're not understanding how Random works. When you create a new instance of Random and do not supply it with a seed value, it will use the current timer value. Do this multiple times in a row quick enough, and each one of the Random instances will return the exact same value! Create a single class-level instance of Random and you can use it throughout the rest of your class code and not have to worry about consecutive instances returning the same values.

              public class Form1 : Form
              {
                  private Random RNG = new Random();
              .
              .
              .
                  private void SomeMethod()
                  {
                      ...
                      int x = RNG.Next(10000);
                      ...
                  }
              }
              

              In your code, you're getting the next random value and putting it in a variable, but then you never use that value in your paint code!

              Member 2458467 wrote:

              you say: "Form_Paint is a bit much for this. I'd create a Control specifically for the purpose ..." I haven't seen you create a Control specifically posted by you for everyone to see ?

              Because I've got my own code to write that nobody is going to write for me and I'm not in the business of writing other peoples code for them. But, yeah, I wrote

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups