Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
Can you believe the MessageBox can show even when the program stopped and the project returned to the design mode after clicking on "Stop debugging"?
 
I couldn't believe that until I tried inserting a command executing MessageBox.Show(...) into the body of the method Paint(...).
 
That's for I want to know when this method is called. I realized that it will be called whenever the DataGridView is redrawn, even when the project in design mode.
 
Could you please explain me how it works? As far as I know, the method will be called directly or indirectly when some event occurs. But I don't see any events associating with that method in the properties window, and even when there's one event for it (for example Paint event) how can it be called when all debugging or compiling or running stopped? Yes, if you do like me, you can't continue designing and coding your project because whenever the main form containing the datagridview with that "playful" method called Paint is redrawn or repainted, it will show a message box, clicking on the OK button will repaint the datagridview anew and a new message box will appear, that makes a loop of calling Paint.
Is there any other method of the same kind to that Paint?
 
Thank you so much!
Posted 31-Mar-11 9:48am
Edited 31-Mar-11 13:10pm
Henry Minute223.6K
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Putting a MsgBox in the Paint event handler is a HORRIBLE idea! When the messagebox is dismissed, guess what happens? The Paint event is probably going to fire again! Well, that is if the messagebox covered any part of the control/form your Paint handler code is servicing.
 
Replace it with Debug.WriteLine or something else so you can monitor it in the debugger without screwing up your painting code.
 
The code is never actually stopped. For example, when you create a custom control and it's being displayed in the designer, your controls code is actually RUNNING, even if you haven't started your app in the debugger. Think about it. How else is the designed going to show your control if it doesn't run the code behind it?
  Permalink  
Comments
King Boy at 31-Mar-11 17:13pm
   
Thank you, however I think only some kinds of code can be run when in design right after compiling, if you change the code and recompile and stop and rewrite that code, it will not run as before. I mean the code seems still to run after stopping debugging, all changes to the code will change the way it works in design time only after restarting debugging and stopping to see how it works a new way in design time. But that seems to happen to some kinds of code. For example, when designing you can't raise event "OnMouseHover" of a button ... and so you can't call the corresponding method or handler.
Another point I still want it to be clear is why is the Paint method called when there is no event associating with it? Or it is automatically? (plus, no events and no command calling it in any parts of the project but it still run when the main form starting.
Thank you so much!
Dave Kreskowiak at 31-Mar-11 18:26pm
   
it will run exactly as coded until it's recomplied. Any components that are updated will be unloaded from the designer, replaced by the compiled code, and reloaded from the new code. Not ALL of the code runs. Just anything that the designer touches, such as anything that involves creating a new instance of the control, Resize, Paint, properties, and any code that those methods touch themselves.
 
"For example, when designing you can't raise event 'OnMouseHover' of a button ... and so you can't call the corresponding method or handler."
Of course not, it's not required to render the control on the design surface. Mouse and Keyboard events don't get raised by the form designer.
 
"Why is Paint called when there is no event associating with it?"
I don't get what you're saying here. The Paint event for a visual control will always get raised if it is dropped on the design surface. How else are you going to see the control if it doesn't raise Paint??
 
The Paint event is called when your application receives a WM_PAINT message in its message pump. That message causes the forms Paint event to be raised, which in turn, causes any controls that need to be painted to have their Paint events raised.
King Boy at 1-Apr-11 1:41am
   
Thank you!!!
Does that mean if I want some codes to be run when Paint event raises, I can put them either in the body of Paint method or any other defined method and associate this to the Paint event?
Anyway partly I can understand what you have explained.
Thank you so much!
Dave Kreskowiak at 1-Apr-11 7:54am
   
Experiment and watch what happens. Just don't use MessageBoxes.
SAKryukov at 1-Apr-11 14:48pm
   
Dave, WM_PAINT mechanism is a really cunning thing. I decided to explain it in my Answer.
As to yours -- you're right, my 5.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Dave is right, but you need some explanation.
Yes, you need to understand it to write other programs.
 
The mechanism is not simple at all. First of all, OnPaint is triggered in response of the Windows message WM_PAINT. The triggering of this message is quite a complex thing. You can see that you method will be fired when any part of your window covered by any other window exposes part of the previously covered surface. So it happens on motion of some windows, on Alt+TAB, on refresh &many; cases.
 
Now, how to trigger it automatically? This is very important for any kind of animation. No, this is not Refresh or anything. Ultimately, this is only one thing: Control.Invalidate. You animate (or otherwise modify) the rendered picture by changing some instance data which is used by OnPaint and the call Invalidate. For better performance, you can use Invalidate with parameter: a Rectangle or Region. Most powerfull thing is Region: it supports all kind of set-theory operations to build any subset of the rendering rectangle.
 
Now, what's so special about WM_PAINT? The processing of this event is very cunning. It does not go through a regular Windows message queue. Instead, it is higly optimized. Imagine you have two invalidates coming one after another, with second one called before your re-rendering (through OnPaint) is not yet complete. Do you think OnPaint is called twice? No way! The messages will be merged together in one in the optimization process, and there invalidated regions will be ORed together. Interesting mechanism, isn't it?
 
There are cases when this technique should be reproduces on application level. With OnPaint and Invalidate you don't have to worry about it.
 
—SA
  Permalink  
Comments
King Boy at 2-Apr-11 8:50am
   
What a pity for I don't understand that mechanism well. I can feel how complex it is, but at my level, I only need to know the method "Paint" is fired automatically. I'm still a newbie in C# programming and many others (such as Windows Messages).
Thank you for your great answer!
Best Regards!
SAKryukov at 2-Apr-11 16:38pm
   
In practice, the application of all this code is reduced to OnPaint and Invalidate, so there is nothing difficult. At to understanding of it, you will hardly need more than described about.
 
By the way, is it enough for your to formally accept this Answer?
 
Thank you.
--SA

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 403
1 OriginalGriff 354
2 George Jonsson 202
3 Shemeemsha RA 148
4 Animesh Datta 130
0 OriginalGriff 6,189
1 Sergey Alexandrovich Kryukov 5,666
2 CPallini 4,810
3 George Jonsson 3,429
4 Gihan Liyanage 2,522


Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 1 Apr 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100