Error "Object reference not set to an instance of an object"

  • Thread starter Thread starter Microsoft
  • Start date Start date
M

Microsoft

When I try this in my code I alwas get an errormessage: "Object reference
not set to an instance of an object"

Dim g As System.Drawing.Graphics
g.DrawString("Test", New Font("Arial", 12, FontStyle.Bold), Brushes.Black,
0, 0)

Why is this?

Marc
 
Um..

Try to not declare it as an instance... sorry I didn't point that out
earlier...

Just directly call System.Drawing.Grapichics.DrawString

or import System.Drawing.Graphics and just call DrawString.
 
Another error I'm afraid (with both solutions):

"Reference to a non-shared member requires an object reference."

Marc
 
Ahhh ok...

You have to get the drawing object from somewhere in your application. it
usually comes from a repaint or such. I forgot about little things like
this (its still early).

Like, a repaint where PaintEventArgs is passed.
 
Hello,

Microsoft said:
When I try this in my code I alwas get an errormessage: "Object reference
not set to an instance of an object"

Dim g As System.Drawing.Graphics
g.DrawString("Test", New Font("Arial", 12, FontStyle.Bold), Brushes.Black,
0, 0)

You never assign an instance of the Graphics class to the instance
variable g. Use something like this:

\\\
Dim g As Graphics = Me.CreateGraphics()
///

or

\\\
Dim bmp As Bitmap = ...
Dim g As Graphics = Graphics.FromImage(bmp)
///

HTH,
Herfried K. Wagner
 
Hmm... I forgot about that too. . Thanks Herfriend! Always a help from
pulling us out of digging a hole. =)
 
I'm a little bit further:

Module Procedures
Friend WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Dim bmp As New Bitmap(1, 1)
Dim g As Graphics = Graphics.FromImage(bmp)

Sub Print()
g.DrawString("Test", New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, 0, 0)
PrintDocument1.Print()
End Sub
End Module

This prints a blank page, not the word "test"???

Marc
 
Marc,
You are drawing on a bitmap, not on the document!

To draw on the document you need to handle the PrintDocument.PrintPage
event. This event has a PrintPageEventArgs parameter. The PrintPageEventArgs
object has a Graphics property. You need to draw on this Graphics object to
have it shown on the document you are attempting to print.

For a reasonable complete sample of using PrintDocument see:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet12242002.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet01282003.asp

Hope this helps
Jay
 
At last, it prints.

But (of course :-) ) I have another question:

I used this code:

Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
e.Graphics.DrawString("Tekst", New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, 0, 0)
End Sub

How can I send printdata from outside the PrintPage eventhandler to the
eventhandler. Something like:

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs, Tekst As String, x As Integer, y
As Integer) Handles PrintDocument1.PrintPage
e.Graphics.DrawString(Tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, x, y)
End Sub

Of course, this desn't work...

Marc
 
Are you talking about adding another handler that happens when printpage is
fireD? I'm confused.
 
No, (Or maybe yes, I don't know) In the first lines of code I showed, all
the work is done in the Eventhandler:

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
e.Graphics.DrawString("Tekst", New Font("Arial", 12,
FontStyle.Bold),Brushes.Black, 0, 0)
End Sub

But what if I want to build the document outside the EventHandler and than
pass it to the Eventhandler to do the printing. Something like this:

Somewhere in a Procedure:
PrintDocument_PrintPage("Tekst", 0, 10)

Eventhandler:
Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs, cTekst As String, x As Integer,
y As Integer
e.Graphics.DrawString(cTekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, x, y)
End Sub

Of course, the code I show doesn't work, but is there another way of doing
this?

Marc
 
If I undertand you right then use RaiseEvent or AddHandler.


Marc said:
No, (Or maybe yes, I don't know) In the first lines of code I showed, all
the work is done in the Eventhandler:

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
e.Graphics.DrawString("Tekst", New Font("Arial", 12,
FontStyle.Bold),Brushes.Black, 0, 0)
End Sub

But what if I want to build the document outside the EventHandler and than
pass it to the Eventhandler to do the printing. Something like this:

Somewhere in a Procedure:
PrintDocument_PrintPage("Tekst", 0, 10)

Eventhandler:
Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs, cTekst As String, x As Integer,
y As Integer
e.Graphics.DrawString(cTekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, x, y)
End Sub

Of course, the code I show doesn't work, but is there another way of doing
this?

Marc

CJ Taylor said:
Are you talking about adding another handler that happens when printpage is
fireD? I'm confused.

Marc said:
At last, it prints.

But (of course :-) ) I have another question:

I used this code:

Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
e.Graphics.DrawString("Tekst", New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, 0, 0)
End Sub

How can I send printdata from outside the PrintPage eventhandler to the
eventhandler. Something like:

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs, Tekst As String, x As
Integer,
y
As Integer) Handles PrintDocument1.PrintPage
e.Graphics.DrawString(Tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, x, y)
End Sub

Of course, this desn't work...

Marc

"Jay B. Harlow [MVP - Outlook]" <[email protected]> schreef in
bericht Marc,
You are drawing on a bitmap, not on the document!

To draw on the document you need to handle the PrintDocument.PrintPage
event. This event has a PrintPageEventArgs parameter. The
PrintPageEventArgs
object has a Graphics property. You need to draw on this Graphics object
to
have it shown on the document you are attempting to print.

For a reasonable complete sample of using PrintDocument see:
http://msdn.microsoft.com/library/d...library/en-us/dnadvnet/html/vbnet01282003.asp
 
Marc,
How can I send printdata from outside the PrintPage eventhandler to the
eventhandler. Something like:
OOP 101? :-|

You cannot modfy the signature of the event handler in .NET. Generally you
need to set class level variables (preferable private) with this data then
the Print event can act on it. Remember the Print event prints an entire
page. It will be called once for each page. Via the PrintPageEventArgs it
lets PrintDocument know there are more pages to print.

Multiple objects can handle the PrintPage event for a single PrintDocument
object. Each could print their 'own part' of the page. This unfortunately
would get very confusing quickly!

Generally what I do is have a collection of objects that I want to print as
a class level variable. This collection of objects all derive from the same
class or implement the same interface. The base class has a Draw method in
it. My PrintPage event handler then uses a For Each on the collection
calling Draw for each object.

Something like:

Public MustInherit Class PrintableElement

Public MustOverride Sub Draw(ByVal gr As Graphics)

End Class

Public Class PrintableString

Private ReadOnly m_tekst As String
Private ReadOnly m_x As Integer
Private ReadOnly m_y As Integer

Public Sub New(tekst as string, x as integer, y as integer)
m_tekst = tekst
m_x = x
m_y = y
End Sub

Public Overrides Sub Draw(ByVal gr As Graphics)
gr.DrawString("Tekst", New Font("Arial", 12, FontStyle.Bold), _
Brushes.Black, 0, 0)
End Sub

End Sub

' m_elements contains classes that derive
' from PrintableElements
Private m_elements As ArrayList


m_elements.Add(New PrintableString("Tekst", 0, 0))

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles
PrintDocument1.PrintPage

For Each element As PrintableElement In m_elements
element.Draw(e.Graphics)
Next

Of course if there are multiple pages, then there is more work involved.

Hope this helps
Jay
 
Not quite yet. Here's what I've done:

I made a new project with a Form.
In this project I made two classes, but I get errors:

Public MustInherit Class PrintableElement
Public MustOverride Sub Draw(ByVal gr As Graphics)
End Class

Public Class PrintableString
Inherits PrintableElement
Private ReadOnly m_tekst As String
Private ReadOnly m_x As Integer
Private ReadOnly m_y As Integer

Public Sub New(ByVal tekst As String, ByVal x As Integer, ByVal y As
Integer)
m_tekst = tekst
m_x = x
m_y = y
End Sub

Public Overrides Sub Draw(ByVal gr As Graphics)
gr.DrawString(m_tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, m_x, m_y)
End Sub
End Class

One module:

Module Module1
Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Public m_elements As ArrayList

Sub PrintDocument1_PrintPage(ByVal Sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim element As New PrintableElement()'PrintableElement' because it contains a 'Mustoverride' member that has not
been overriden"get an error on element: "Argument not specified for parameter 'y' of
'Public sub new (tekst as string, x as integer, y as integer)'"

For Each element In m_elements
element.Draw(e.Graphics)
Next
End Sub
End Module

One button on the form:

Public Class Form1
Inherits System.Windows.Forms.Form

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
m_elements.Add(New PrintableString("Tekst", 0, 0))
End Sub
End Class


Marc

Marc said:
I think I get it. I'll try this out to be sure ;-)

Thanks a lot for all the answers!

Marc

Jay B. Harlow said:
Marc,
OOP 101? :-|

You cannot modfy the signature of the event handler in .NET. Generally you
need to set class level variables (preferable private) with this data then
the Print event can act on it. Remember the Print event prints an entire
page. It will be called once for each page. Via the PrintPageEventArgs it
lets PrintDocument know there are more pages to print.

Multiple objects can handle the PrintPage event for a single PrintDocument
object. Each could print their 'own part' of the page. This unfortunately
would get very confusing quickly!

Generally what I do is have a collection of objects that I want to print as
a class level variable. This collection of objects all derive from the same
class or implement the same interface. The base class has a Draw method in
it. My PrintPage event handler then uses a For Each on the collection
calling Draw for each object.

Something like:

Public MustInherit Class PrintableElement

Public MustOverride Sub Draw(ByVal gr As Graphics)

End Class

Public Class PrintableString

Private ReadOnly m_tekst As String
Private ReadOnly m_x As Integer
Private ReadOnly m_y As Integer

Public Sub New(tekst as string, x as integer, y as integer)
m_tekst = tekst
m_x = x
m_y = y
End Sub

Public Overrides Sub Draw(ByVal gr As Graphics)
gr.DrawString("Tekst", New Font("Arial", 12,
FontStyle.Bold),
_
Brushes.Black, 0, 0)
End Sub

End Sub

' m_elements contains classes that derive
' from PrintableElements
Private m_elements As ArrayList


m_elements.Add(New PrintableString("Tekst", 0, 0))

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles
PrintDocument1.PrintPage

For Each element As PrintableElement In m_elements
element.Draw(e.Graphics)
Next

Of course if there are multiple pages, then there is more work involved.

Hope this helps
Jay


Marc said:
At last, it prints.

But (of course :-) ) I have another question:

I used this code:

Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
e.Graphics.DrawString("Tekst", New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, 0, 0)
End Sub

How can I send printdata from outside the PrintPage eventhandler to the
eventhandler. Something like:

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs, Tekst As String, x As
Integer,
y
As Integer) Handles PrintDocument1.PrintPage
e.Graphics.DrawString(Tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, x, y)
End Sub

Of course, this desn't work...

Marc

"Jay B. Harlow [MVP - Outlook]" <[email protected]> schreef in
bericht Marc,
You are drawing on a bitmap, not on the document!

To draw on the document you need to handle the PrintDocument.PrintPage
event. This event has a PrintPageEventArgs parameter. The
PrintPageEventArgs
object has a Graphics property. You need to draw on this Graphics object
to
have it shown on the document you are attempting to print.

For a reasonable complete sample of using PrintDocument see:
http://msdn.microsoft.com/library/d...library/en-us/dnadvnet/html/vbnet01282003.asp
 
Marc,
Neither of these belong in the PrintPage event handler, you need to fill the
ArrayList before you call PrintDocument.Print method!
Sub PrintDocument1_PrintPage(ByVal Sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim element As New PrintableElement()

You don't want an instance of a class here, you just want a variable:
Sub PrintDocument1_PrintPage( ...

Dim element As PrintableElement
For Each element In m_elements
element.Draw(e.Graphics)
Next
End Sub

You use 'As New' when you want an instance of a class created, here you
don't as the For Each will set the element variable to each instance of the
class in the ArrayList.

PrintableElement is what is known as a Abstract Base Class . It is a
template used to define other objects, Abstract Base Classes are used for
Polymorphism. Your PrintPage event handler knows about the PrintableElement
class, it uses the Draw method. The Draw method is polymorphic. However the
array list actually contains PrintableString elements. The PrintableString
is what is known as a Concrete class. It offers an implementation for the
PrintableElement.Draw method. Although the PrintPage method is calling
PrintableElement.Draw indirectly it is executing the PrintableString.Draw
method. You can extend this to have a PrintableLine class that inherits from
PrintableElement. The PrintableLine.Draw method would draw a line, instead
of drawing text. The PrintPage method doesn't care as it is still calling
PrintableElement.Draw, for a PrintableLine object in the ArrayList, the
PrintableLine.Draw method would be indirectly called.

A Sample PrintableLine class:

Public Class PrintableLine
Inherits PrintableElement

Private ReadOnly m_pt1 As Point
Private ReadOnly m_pt2 As Point

Public Sub New(ByVal pt1 As Point, pt2 As Point)
m_pt1 = pt1
m_pt2 = pt2
End Sub

Public Overrides Sub Draw(ByVal gr As Graphics)
gr.DrawLine(Pens.Black, m_pt1, m_pt2)
End Sub

End Class

Hope this helps
Jay


Marc said:
Not quite yet. Here's what I've done:

I made a new project with a Form.
In this project I made two classes, but I get errors:

Public MustInherit Class PrintableElement
Public MustOverride Sub Draw(ByVal gr As Graphics)
End Class

Public Class PrintableString
Inherits PrintableElement
Private ReadOnly m_tekst As String
Private ReadOnly m_x As Integer
Private ReadOnly m_y As Integer

Public Sub New(ByVal tekst As String, ByVal x As Integer, ByVal y As
Integer)
m_tekst = tekst
m_x = x
m_y = y
End Sub

Public Overrides Sub Draw(ByVal gr As Graphics)
gr.DrawString(m_tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, m_x, m_y)
End Sub
End Class

One module:

Module Module1
Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Public m_elements As ArrayList

Sub PrintDocument1_PrintPage(ByVal Sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim element As New PrintableElement()'PrintableElement' because it contains a 'Mustoverride' member that has not
been overriden"get an error on element: "Argument not specified for parameter 'y' of
'Public sub new (tekst as string, x as integer, y as integer)'"

For Each element In m_elements
element.Draw(e.Graphics)
Next
End Sub
End Module

One button on the form:

Public Class Form1
Inherits System.Windows.Forms.Form

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
m_elements.Add(New PrintableString("Tekst", 0, 0))
End Sub
End Class


Marc

Marc said:
I think I get it. I'll try this out to be sure ;-)

Thanks a lot for all the answers!

Marc

print
as
method
in
it. My PrintPage event handler then uses a For Each on the collection
calling Draw for each object.

Something like:

Public MustInherit Class PrintableElement

Public MustOverride Sub Draw(ByVal gr As Graphics)

End Class

Public Class PrintableString

Private ReadOnly m_tekst As String
Private ReadOnly m_x As Integer
Private ReadOnly m_y As Integer

Public Sub New(tekst as string, x as integer, y as integer)
m_tekst = tekst
m_x = x
m_y = y
End Sub

Public Overrides Sub Draw(ByVal gr As Graphics)
gr.DrawString("Tekst", New Font("Arial", 12,
FontStyle.Bold),
_
Brushes.Black, 0, 0)
End Sub

End Sub

' m_elements contains classes that derive
' from PrintableElements
Private m_elements As ArrayList


m_elements.Add(New PrintableString("Tekst", 0, 0))


Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles
PrintDocument1.PrintPage

For Each element As PrintableElement In m_elements
element.Draw(e.Graphics)
Next

End Sub

Of course if there are multiple pages, then there is more work involved.

Hope this helps
Jay


At last, it prints.

But (of course :-) ) I have another question:

I used this code:

Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles
PrintDocument1.PrintPage
e.Graphics.DrawString("Tekst", New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, 0, 0)
End Sub

How can I send printdata from outside the PrintPage eventhandler to the
eventhandler. Something like:

Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs, Tekst As String, x As Integer,
y
As Integer) Handles PrintDocument1.PrintPage
e.Graphics.DrawString(Tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, x, y)
End Sub

Of course, this desn't work...

Marc

"Jay B. Harlow [MVP - Outlook]" <[email protected]> schreef in
bericht Marc,
You are drawing on a bitmap, not on the document!

To draw on the document you need to handle the PrintDocument.PrintPage
event. This event has a PrintPageEventArgs parameter. The
PrintPageEventArgs
object has a Graphics property. You need to draw on this Graphics object
to
have it shown on the document you are attempting to print.

For a reasonable complete sample of using PrintDocument see:
http://msdn.microsoft.com/library/d...library/en-us/dnadvnet/html/vbnet01282003.asp
 
Yes, I can follow this (I use Visual Foxpro for a couple of years, so I know
about Abstract Classes).

The problem is that it doesn't work this way.

Here's what I have so far:

Public MustInherit Class PrintableElement
Public MustOverride Sub Draw(ByVal gr As Graphics)
End Class

Public Class PrintableString
Inherits PrintableElement
Private ReadOnly m_tekst As String
Private ReadOnly m_x As Integer
Private ReadOnly m_y As Integer

Public Sub New(ByVal tekst As String, ByVal x As Integer, ByVal y As
Integer)
m_tekst = tekst
m_x = x
m_y = y
End Sub

Public Overrides Sub Draw(ByVal gr As System.Drawing.Graphics)
gr.DrawString(m_tekst, New Font("Arial", 12, FontStyle.Bold),
Brushes.Black, m_x, m_y)
End Sub
End Class

Module Module1
Private WithEvents PrintDocument1 As New
System.Drawing.Printing.PrintDocument()
Public m_elements As ArrayList

Sub PrintDocument1_PrintPage(ByVal Sender As Object, ByVal e As
System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim element As PrintableElement
For Each element In m_elements
element.Draw(e.Graphics)
Next
End Sub
End Module

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
m_elements.Add(New PrintableString("Tekst", 0, 10))
End Sub

When I click on the button I get an error:
'Object reference not set to an instance of an error'

That's what it all began with...

Marc
 
Sorry, forgot something:

The error happens on the line

m_elements.Add(New PrintableString("Tekst", 0, 10))

Marc
 
Back
Top