barski Posted March 11, 2006 Posted March 11, 2006 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 Quote
Leaders Iceplug Posted March 11, 2006 Leaders Posted March 11, 2006 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. Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
Cags Posted March 11, 2006 Posted March 11, 2006 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). Quote Anybody looking for a graduate programmer (Midlands, England)?
Cags Posted March 11, 2006 Posted March 11, 2006 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. Quote Anybody looking for a graduate programmer (Midlands, England)?
barski Posted March 11, 2006 Author Posted March 11, 2006 like i said earlier i just started tinkering with the gdi so the thorough explanation is greatly appreciated! Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.