Connecting Tech Pros Worldwide Forums | Help | Site Map

C# Control Paint Succesion

tranc3d's Avatar
Newbie
 
Join Date: Oct 2008
Location: Sibiu, Romania
Posts: 11
#1: Oct 23 '08
I want to understand the mechanism behind the painting of a control: what are the functions (handlers) involved and when they are called.

I have a custom control based on a Panel. I think the functions involved for this examples are: OnPaint handler in Panel class, OnPaint handler in CustomPanel class and OnPaint event handler of the CustomPanel in the main form (from de designer).

1.OnPaint of Panel Class (what does this do and when is it called?)
2.OnPaint of CustomPanel Class (here i have base.OnPaint() and extra code for displaying a image in the viewable are of the Panel in an optimised way, for smooth scrolling)
3.OnPaint in main form (here is code for displaying some selection rectangles over the image)

The problem is that the rectangles are, i think, behind the image (the image is painted after the rectangles are painted?). The OnPaint handler gets called. When i scroll the image the rectangles flicker.

Before this custom panel, i used PictureBox control which had a Image property in which i put the current viewable part of the image based upon the values of two scrollbars which controlled the scrolling, and in the OnPaint event handler i did the drawing of the selection rectangles. Everything worked fine, but the scrolling speed became more and more slow proportional with the dimensions of the image (i generated the viewable part of the image with DrawImage()).

What changes should i do, in order to see the ractangles? And i would like to know what is the mechanism behind it, and in the future i won't come with this stupid questions :)

Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,161
#2: Oct 23 '08

re: C# Control Paint Succesion


Your rectangles are drawn in your Paint event handler in your application right?
Like you have you Form, and you add this CustomPanel control to it, say you called it myCustomPanel.
Then you attached an event handler on myCustomPanel to the Paint event?

So now you have:
Inside the CustomPanel class you have overriden the OnPaint function
In your regular program, attached an event handler to the Paint function of the instance of the CustomPanel class (mycustomPanel)

When the control is told to redraw itself, the OnPaint INSIDE the CustomPanel class is called. Since you have overridden it, it will execute *YOUR* version of the OnPaint function. When you call base.OnPaint() it will execute the built-in version of OnPaint() (which for say a Button control would be where they draw the visuals that make it 'look like a button' ) It is also what triggers the Paint() event to be fired.
So whenever you call base.OnPaint(), all of the original control-specific visuals are drawn, and the Paint() event is fired. All of which will probably happen before *YOUR* OnPaint() function goes on to the next line of code.

So I guess maybe to answer your question, call base.OnPaint() as the LAST thing inside your overridden OnPaint() function, to make sure all your custom drawings occur FIRST, then the Paint event happens after.
tranc3d's Avatar
Newbie
 
Join Date: Oct 2008
Location: Sibiu, Romania
Posts: 11
#3: Oct 24 '08

re: C# Control Paint Succesion


Quote:
When the control is told to redraw itself, the OnPaint INSIDE the CustomPanel class is called. Since you have overridden it, it will execute *YOUR* version of the OnPaint function.
in the paint event handler in my form which has overriden the OnPaint event in the CustomPanel class which drew the image, i draw the rectangles. The image appears (the onpaint event handler in the CustomPanel class gets exexuted. Why? I overrided it and int this one there is no explicit call to base.OnPaint() ). The rectangles appear flickering only when i scroll the image. Could you be more specific in your explanation?
tranc3d's Avatar
Newbie
 
Join Date: Oct 2008
Location: Sibiu, Romania
Posts: 11
#4: Oct 24 '08

re: C# Control Paint Succesion


Quote:
So I guess maybe to answer your question, call base.OnPaint() as the LAST thing inside your overridden OnPaint() function, to make sure all your custom drawings occur FIRST, then the Paint event happens after.
Nope, the same thing
Plater's Avatar
Moderator
 
Join Date: Apr 2007
Location: New England
Posts: 7,161
#5: Oct 24 '08

re: C# Control Paint Succesion


Hmm. I will investigate more.

Expand|Select|Wrap|Line Numbers
  1. public partial class CustomPanel : Panel
  2. {
  3.    public CustomPanel()
  4.    {
  5.       InitializeComponent();
  6.    }
  7.    protected override void OnPaint(PaintEventArgs e)
  8.    {
  9.       Debug.WriteLine("Overriden OnPaint Called"); 
  10.       base.OnPaint(e);
  11.       Debug.WriteLine("Called base.OnPaint(e), exiting overriden OnPaint()");
  12.    }
  13. }//end of class
  14.  
Expand|Select|Wrap|Line Numbers
  1. CustomPanel cp = new CustomPanel();
  2. cp.Paint += new PaintEventHandler(cp_Paint);
  3.  
  4.  
  5. void cp_Paint(object sender, PaintEventArgs e)
  6. {
  7.    System.Diagnostics.Debug.WriteLine("Paint event handler called");
  8. }
  9.  
When I use that sample code, the output looks like this:
Quote:
Overriden OnPaint Called
Paint event handler called
Called base.OnPaint(e), exiting overriden OnPaint()
If I remove the base.onPaint call, "Paint event handler called" never appears
tranc3d's Avatar
Newbie
 
Join Date: Oct 2008
Location: Sibiu, Romania
Posts: 11
#6: Oct 27 '08

re: C# Control Paint Succesion


That's strange, i'll review my code. Thanks for the help.
Reply