Draw Line of Form?

E

Ed Bitzer

Can draw a line on my form with a button click event but cannot upon the
Load event when I wish. No more line object so used the following:
Dim bit As Bitmap = New Bitmap(Me.Width, Me.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(Color.Blue, 1)
Me.CreateGraphics.DrawLine(myPen, 0, 5, Me.Width, 5)
Appreciate some help.

Ed
 
H

Herfried K. Wagner [MVP]

Ed,

Ed Bitzer said:
Can draw a line on my form with a button click event but cannot upon the
Load event when I wish. No more line object so used the following:
Dim bit As Bitmap = New Bitmap(Me.Width, Me.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(Color.Blue, 1)
Me.CreateGraphics.DrawLine(myPen, 0, 5, Me.Width, 5)


At the time when the form's 'Load' event is raised, the form is not yet
visible. Thus the drawing will not be visible when the form is shown. In
..NET's drawing model, drawings need to be renewed whenever a part of the
form which is obscured gets visible again. You may want to place your
drawing code in the form's 'Paint' event handler or an overridden 'OnPaint'
method. These methods will be called whenever a part of the form needs to
be redrawn:

\\\
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
e.Graphics.DrawLine(Pens.Blue, 0, 5, Me.Width, 5)
End Sub
///

Don't fotget to call the 'Dispose' method of 'Graphics' and 'Pen' objects
you created yourself ('CreateGraphics', 'New Pen(...)') when you don't need
them any more.
 
M

Martin Horn

Don't fotget to call the 'Dispose' method of 'Graphics' and 'Pen' objects
you created yourself ('CreateGraphics', 'New Pen(...)') when you don't
need them any more.

Doesn't the Garbage Collector handle this sort of thing once they go out of
scope? Apologies if this is a silly question.

Martin.
 
H

Herfried K. Wagner [MVP]

Martin,

Martin Horn said:
Doesn't the Garbage Collector handle this sort of thing once they go out
of scope? Apologies if this is a silly question.

..NET doesn't support deterministic finalization of objects as known from
COM/VB6. The GC will destroy the object, but this will not occur
immediately when all reachable references to the object are released.
'Graphics' and 'Pen' use unmanaged resources (GDI handles). By calling
'Dispose' directly these resources are released immediately, which can
prevent the application from missing unmanaged resources.
 
E

Ed Bitzer

Herfried,

Understand and as indicated if I place in the Paint event I the lines are
displayed. Of course I tried to extrapolate my new knowledge but was not
able to use the same logic with a PictureBox. If I add a PictureBox to the
load event on my form and then try to draw lines using the same approach
placing the line drawing code in the PictureBox even - no work. I of course
did change all references to Me in the Form example to PictureBox. Is that
as simply explainable?

Ed
 
G

Guest

Bob, I've seen a lot of posts saying CreateGraphics is a bad Idea, mostly
they say because of encapuslation and it doesn't work with double buffering.
I've yet to really understand why it is a bad to use it so long as one
doesn't use double buffering...is there some fear that this won't work in
future releases of VB.Net and if so, why aren't we worried about several
other things the probably will change in future releases? Why the
CreateGraphics worry..do you have some insight as to what Microsoft will do?
 
B

Bob Powell [MVP]

The problem with using the CreateGraphics call for any purpose other than
obtaining data about the Graphics object of a particular window is that it
breaks the fundamental principle of event driven programming.

Windows is an event driven system in which things happen in order and for a
purpose. When you write code that refuses to follow the order of events as
dictated by the system you will have your own misguided efforts walked upon
by the *correct functioning* of the system.

Painting using CreateGraphics will almost inevitably be overprinted by the
OnPaint method and causes huge numbers of questions from inexperienced
programmers who think that there is some sort of system error when it's
their own code that's at fault. This is why it's still the GDI+ FAQ most
asked question despite three years of the answer being available for all to
see with a simple google search.

It's also why I generally answer such questions with a brusque "RTFM" style
answer so, after you've "Read That Fine Material" ;-) you'll understand
fully.

Microsoft's operating systems, including Longhorn, will continue to be event
driven and will exhibit the same behaviours if event order is ignored
whether it's GDI, GDI+ or Avalon doing the drawing.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
H

Herfried K. Wagner [MVP]

Ed,

Ed Bitzer said:
Understand and as indicated if I place in the Paint event I the lines are
displayed. Of course I tried to extrapolate my new knowledge but was not
able to use the same logic with a PictureBox. If I add a PictureBox to
the load event on my form and then try to draw lines using the same
approach placing the line drawing code in the PictureBox even - no work.
I of course did change all references to Me in the Form example to
PictureBox. Is that as simply explainable?

I assume that you took the 'OnPaint' code I posted and tried to use it for a
picturebox placed on a form. This won't work, because 'OnPaint' is a
protected method that can only be overridden in a class that derives from
the base class containing this method. So, there are two solutions:

Simple solution: Instead of overriding 'OnPaint', simply add a handler to
the picturebox's 'Paint' event. To do that, open the code editor window,
choose the picturebox from the left combobox (which is on top of the code
editor) and select 'Paint' in the combobox on the right side. An event
handler will be generated automatically. All you need to do is simply
entering your drawing code in the event handler.

Complicated solution: Create a new class that inherits from 'PictureBox'
and overrides its 'OnPaint' method. Then use this extended picturebox class
instead of the standard picturebox control.
 
G

Guest

Thanks for your time in answering my question. I use the graphics object
passed by the "OnPaint" event for the most part but I do have one usercontrol
that creates a graphics object for the control when it's first instantiated
then re-creates the graphics object each time the control is moved or
resized...this seems to work OK as I've used it a lot. I do plan, however,
to convert it to drawing on a bitmap then BltBit copying the parts that need
refreshed in the OnPaint event when I get time.
 
E

Ed Bitzer

Herfried,

You do more than yeoman's work for this forum and I do appreciate the
tutoring. I will drag out one more round. I did not see you OnPaint but
just blindly dove in. I have tried the PictureBox again selecting
PictureBox and then Paint as suggested - the following code does nothing.
If I replace PictureBox1 with Me.CreateGraphics, it draws on the form but
behind the PictureBox. Does that follow the rules ? Sure would love to
have it draw on the PictureBox

Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
Dim c, i As Short
Dim inc As Short
Dim bit As Bitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(Color.Red, 1)
c = 10
inc = 20
For i = 0 To 30
PictureBox1.CreateGraphics.DrawLine(myPen, PictureBox1.Left, c + i *
inc, PictureBox1.Width, c + i * inc)
Next
myPen.Dispose()
g.Dispose()
End Sub

Ed
 
A

aatcbbtccctc

Bob Powell [MVP] wrote:

(snip)
Microsoft's operating systems, including Longhorn, will continue to be event
driven and will exhibit the same behaviours if event order is ignored
whether it's GDI, GDI+ or Avalon doing the drawing.


"GDI+ no longer supported in LongHorn" - Bob Powell!

TC
 
H

Herfried K. Wagner [MVP]

Ed,

Ed Bitzer said:
You do more than yeoman's work for this forum and I do appreciate the
tutoring. I will drag out one more round. I did not see you OnPaint but
just blindly dove in. I have tried the PictureBox again selecting
PictureBox and then Paint as suggested - the following code does nothing.
If I replace PictureBox1 with Me.CreateGraphics, it draws on the form but
behind the PictureBox. Does that follow the rules ?

Well, yes, because you are retreiving a 'Graphics' object for the /form/ and
not the picturebox.
Sure would love to have it draw on the PictureBox

I suggest not to use 'CreateGraphics'. Instead, you can access the
'Graphics' object for the picturebox in the 'e' parameter of your 'Paint'
event handler ('e.Graphics').
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
Dim c, i As Short
Dim inc As Short
Dim bit As Bitmap = New Bitmap(PictureBox1.Width, PictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(bit)
Dim myPen As Pen = New Pen(Color.Red, 1)
c = 10
inc = 20
For i = 0 To 30
PictureBox1.CreateGraphics.DrawLine(myPen, PictureBox1.Left, c + i *

Replace 'PictureBox1.CreateGraphics.DrawLine' with 'e.DrawLine'. This
should solve the problem.
 
E

Ed Bitzer

Herfried,

And it does as advertised. I just to have to get a third book to learn my
fundamentals so that I can use the help system which truly is extensive -
you just have to have the fundamentals down first. Glad I don't do this for
a living<g>.



I do thank you,



Ed
 
H

Herfried K. Wagner [MVP]

Ed,

Ed Bitzer said:
And it does as advertised. I just to have to get a third book to learn my
fundamentals so that I can use the help system which truly is extensive -
you just have to have the fundamentals down first.

Feel free to ask if you have any further questions.
Glad I don't do this for a living<g>.

;-)
 
G

Guest

Then what you are saying is that Longhorn will not support the CreateGraphics
method...is this correct? If so, then what other things won't be backward
compataible with VB.Net?
 
A

aatcbbtccctc

Hi Dennis

Sorry, I only just saw your reply.

On April 1, Bob Powell [MVP] posted to
microsoft.public.dotnet.framework, subject: "GDI+ no longer supported
in LongHorn", saying that GDI+ would not be supported in LongHorn.

I thought that this was probably an April Fool's joke. However, I do
not work in the .NET environment yet, and I have recently been
suffering some major grief in regard to Microsoft's "start again" move
from VB[A] to VB.NET. So his post did not seem obviously unreasonable,
given Microsoft's blunt abandonment of older applications comprising
millions of lines of VB[A] code. Most of that code will have to be
rewritten from scratch. This will put many one-man shops, like me, out
of business.

I asked him to confirm that his post was a joke, but he did not reply.
That was very stupid, in my opinion, unless it was actually true. But I
*think* that it was a joke, because no-one else has objected, so far.

Cheers,
TC
 
A

aatcbbtccctc

And why should I care about GDI+? Because I have spent the past 6
months integrating the redistributable gdiplus.dll into my 75,000 line
VBA applicaton :-((

TC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top