Jump to content
Xtreme .Net Talk

Recommended Posts

Posted
i've just started tinkering with gdi and have a very basic question. attached is form class that fills a rectangle and it works but when i resize it the information from the original rectangle is retained therefore causing it to look less than great. any info on what i'm missing here would be nice.

Form1.txt

  • Leaders
Posted
The question is how can you tell that the rectangle stays the same? According to your rectangle set up, the rectangle is always extending 100 pixels from the left end all the way over to the right from top to bottom.

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted
The question is how can you tell that the rectangle stays the same? According to your rectangle set up' date=' the rectangle is always extending 100 pixels from the left end all the way over to the right from top to bottom.[/quote']

I assume barski means because of the errors in the gradient. In certain cases, resizing the form causes odd patterns to appear in gradient (giving an effect similar to offset stacked squares, assumbably something todo with the size changes during resize). I've had a reasonable amount of experience using GDI+ and I couldn't fix the problem (at least I couldn't fix it in the few minutes I spent).

Anybody looking for a graduate programmer (Midlands, England)?
Posted

Ok, I obviously wasn't thinking hard enough last time as I managed to fix it this time. Heres some stuff you need to know...

 

Firstly drawing in the OnPaint event is not always the quickest method of achieving what you want. As a general rule I like to keep by OnPaint method as clear as possible so I do all drawing to a 'BackBuffer', which in my case is a Bitmap object. The only code I would put in the OnPaint method is as follows.

	protected override void OnPaint(PaintEventArgs e)
	{
                       // buffer is a Bitmap object declared at the top of the form
                       // and initialised (at least to start with) in the contructor.
		if(buffer != null)
			e.Graphics.DrawImageUnscaled(buffer, 0, 0);
	}

Now your probably thinking well thats nice but it doesn't draw anything, in which case your quite right. So we also need to add code to draw to the buffer. The way I generally do this is by creating a method called Draw().

	private void Draw()
	{
		// load buffer into a graphics object
		System.Drawing.Graphics graphx = Graphics.FromImage(buffer);						
		
		// create objects
		System.Drawing.Rectangle rect = new Rectangle(0,0,this.Width,this.Height);			
		System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(rect,System.Drawing.Color.Blue,System.Drawing.Color.Gray,System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);		
		
		// draw to buffer
		graphx.FillRectangle(brush,rect);	
		
		// dispose of objects to prevent memory leak
		brush.Dispose();
		graphx.Dispose();

		// tell the application to update the screen (which essential calls OnPaint)
		Invalidate();
	}

This piece of code does all the drawing operations, painting everything to the buffer. So we need to call this section of code whenever we need to change something. Now in the case of resizing the form we need todo two things. Firstly resize the buffer so that it is the right size again and secondly call the draw method all over again.

	private void Form1_Resize(object sender, System.EventArgs e)
	{
		buffer = new Bitmap(this.Width, this.Height);
		Draw();
	}

If you were to run the application at this stage you should notice that everything looks ok, but the Form appears to flash during Resize. This is because OnPaintBackground is called before OnPaint, in situations where you are painting all or the majority of the Control/Form you should Override this method to prevent it from drawing the background first. (alternatively you could draw as part of that method instead, but I tend to stick with the OnPaint method.)

	protected override void OnPaintBackground(PaintEventArgs pevent)
	{
                       // comment out to avoid flicker
		// base.OnPaintBackground (pevent);
	}

Right I think that covers most aspects of the method I use to buffer controls. Other people may do it differently but this method has served me well.

Anybody looking for a graduate programmer (Midlands, England)?

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...