Using Graphics

Reading MSDN I found a code like this:

System.Drawing.Pen myPen; myPen = new System.Drawing.Pen(System.Drawing.Color.Red); System.Drawing.Graphics formGraphics = this.CreateGraphics(); formGraphics.DrawLine(myPen, 0, 0, 200, 200); myPen.Dispose(); formGraphics.Dispose();
I copied it to a WindwsApplication project like this:using System;using System.Collections.Generic;
using System.ComponentModel;
using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace WindowsApplication1{publicpartialclassForm1 :Form
{
public Form1(){InitializeComponent();System.Drawing.Pen myPen;myPen =new System.Drawing.Pen(System.Drawing.Color.Red);System.Drawing.Graphics formGraphics =this.CreateGraphics();formGraphics.DrawLine(myPen, 0, 0, 200, 200);myPen.Dispose();formGraphics.Dispose();}}}When I run this WindowsAplication I get an empty Form ( there is no line on it).I have similar problems when I try to use other Pen and Graphics shapes.Could somedoby help me please in using graphics?Thank you in advance
[2467 byte] By [stece] at [2008-1-10]
# 1

hi

if you don't override OnPaint Event, you will lose all of your paintings in each refresh. so the best place to draw is inside this event. just like:

protected override void OnPaint(PaintEventArgs e)
{
// let Windows paint everything that needs repainting
base.OnPaint(e);

// your drawing goes here, use e.Graphics
}

ashk1860 at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 2

One thing still bothers me, why there is in MSDN a code for drawing a line like this :

System.Drawing.Pen myPen; myPen = new System.Drawing.Pen(System.Drawing.Color.Red); System.Drawing.Graphics formGraphics = this.CreateGraphics(); formGraphics.DrawLine(myPen, 0, 0, 200, 200); myPen.Dispose(); formGraphics.Dispose();

and you had showed me and explained that lines like this :

System.Drawing.Graphics formGraphics = this.CreateGraphics();

can't be used ?

Additionaly MSDN says:

Compiling the Code

This example requires:

  • A Windows Application project.

The code needs to be within the scope of the form class. The instance of the form is represented by this.

Thank you in advance
stece at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 4
I'm sorry for duplication, but it helped me to know override method written by ashk1860 . Anyway I stop doing that.
stece at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 5

ashk1860

There is no reason for overriding the OnPaint method. One of the last things this method does is to raise the Paint event, that is, execute all handlers for the Paint event (RaiseEvent is just replaced with delegate.Invoke). Therefore, if you draw inside a handler for the Paint event, the code will be executed exactly in the place you have shown it.

CarstenKanstrup at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 6
The code is valid, if used at the right time and in the right place. The form's constructor is not the right place. Still, it is a crummy example, 98% of the time you'll want to do your drawing in the Paint event. Drawing with CreateGraphics() is only suitable for doing fast animations. What MSDN topic has this example?

There is no fundamental difference between using the Paint event vs overriding OnPaint(). OnPaint() is often much more convenient. It will however make a big difference when you derive a new form from your existing form.

nobugz at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 7

The Vertical Bargraph thread http://forums.microsoft.com/msdn/showpost.aspx?postid=1536317&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=1 is a good example of the two methods - the MSDN topic you search. Please forget my first prototypes - at that time I was pretty new to VB programming. Compare my last post with the one from SJW.

The problem with the Paint event is that it is usually fired as the consequence of an Invalidate() call (OnPaint method). This means that in many cases, the entier form is redrawn each time just a single pixel needs to be changed. This is a terrible waist of resources. Besides, CreateGraphics is one of the four thread safe methods, so in the bargraph example where the data come in through the serial port, it even ought to be possible (not tested) to draw directly from the eventhandler for the DataReceived event (thread pool thread), which further speeds up the situation.

Unfortunately, I have not been able to find any good description of CreateGraphics. What happens behind the scenes? For example, why must you create a new graphics each time you want to draw and then dispose it immediately after the drawing instead of keeping a more static graphics? The help files says that the graphics is the canvas on which you draw, but I don't destroy my paper and take a new one each time I want to draw a new line.

CarstenKanstrup at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 8
Thanks to all of you for your time and effort to help me.
stece at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 9
thanks Carsten.
ashk1860 at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 10

Carsten wrote: "The help files says that the graphics is the canvas on which you draw, but I don't destroy my paper and take a new one each time I want to draw a new line."

In this analogy of paper and pen, I would think of the paper as the canvas and the pen as the instrument that I (the graphics) use to draw. All of us are drawing to the same canvas. We could be drawing at the same point on the canvas at the same time.

JohnWein at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 11

Yes, but why do we have to create and dispose it all the time? It would be much more natural to create it when you open your application and then dispose it when you close it, but this is not possible - why?

CarstenKanstrup at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 12

Why is it not possible? It's discouraged because it ties up system resources.

JohnWein at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 13

Which system resources?

In the case with the bargraph display:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

....

Dim barGraphics As Graphics = PictureBox1.CreateGraphics

barGraphics.FillRectangle(Brushes.Black, 0, 256 - OldValue, 20, OldValue - InputValue)

barGraphics.Dispose()

Each time the handler is called, a new graphich has to be created and disposed shortly after. You are not allowed to move the "Dim barGraphics" statement outside the handler as a global variable (I have tried). Why?

CarstenKanstrup at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 14

But this is fine:

Code Block

Public Class Form1

Dim g As Graphics = Me.CreateGraphics

End Class

This link may help explain why: http://msdn2.microsoft.com/en-us/library/ms533234.aspx

Personally I would like other applications to use the minimum necessary resources at all times and I try to do the same. If a resource has a dispose method, use it only when and while you need it and dispose it after you use it.
JohnWein at 2007-10-3 > top of Msdn Tech,Windows Forms,Windows Forms General...