Good Friday
Good Friday

Reputation: 1

NullReferenceException and/or variable usage before it has been assigned

I am new to .net and am doing my best to understand the Nuances (or Nuisance). I am trying to print text on a form. I did find many examples of the Graphics class, DrawString() etc. Unfortunately, I cannot get any of them to work. The stumbling block for me seems to be the error “NullReferenceException” and/or the warning “variable usage before it has been assigned”. One example found at "http://msdn.microsoft.com/en-US/library/76c5db29(v=vs.80).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1". vs2005 displays the warning "Variable 'myE' is used before it has been assigned a value. A null referene excpetion could result at runtime and sure enough when I run a NullReferenceException is thrown at "e.Graphics.DrawString(drawString, drawFont, drawBrush, drawPoint)" How do I fix this?

Public Class Form1
    Public Sub DrawStringPointF(ByVal e As PaintEventArgs)
        Dim drawString As [String] = "Sample Text"
        Dim drawFont As New Font("Arial", 16)
        Dim drawBrush As New SolidBrush(Color.Black)
        Dim drawPoint As New PointF(150.0F, 150.0F)
        e.Graphics.DrawString(drawString, drawFont,drawBrush, drawPoint)
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim myE As PaintEventArgs
        DrawStringPointF(myE)
    End Sub
End Class

Upvotes: 0

Views: 556

Answers (2)

Athena
Athena

Reputation: 3228

Your question is broader than your problem. You're asking what a null reference exception is; this question has been answered many times elsewhere. A NRE (NullReferenceException) is referring to a variable that isn't defined at all

We can think about memory as being a vast, open parking lot. When you define a variable, using a statement like this,

Dim myObject as Integer

... you're claiming one or more of the parking spaces in the parking lot. However, all you've done is declare that this spot is yours, but not what goes in it. To give it a value, simply use the equals operator.

myObject = 100

Simple objects, known as primitives, like strings, numbers and characters, have an implied value when they're not defined. For example, integers are assumed to be zero if they have no value.

In your program, when you get a NRE, mouse over each argument in the function and the object that the function is being called from. If any of them claim to have a value of Nothing, there's your problem. You've reserved space for your object, but not yet given it a value.

As SLaks said, your specific problem is related to how you're calling the method, but without a strong understanding of what Nothing means, it may not correctly address the underlying question>

Finally, let's look at code that's specifically yours. You call Dim myE as PaintEventArgs.

In this statement, you have reserved space in the memory- that is to say, claimed a parking space we talked about earlier. However, it does NOT have a value! It's empty. The program cannot function properly because you're telling it to perform an action on something that doesn't exist. To fix it, use the New operator. When making new objects, first reserve them in memory (Dim actually stands for "define in memory") and then give them a value with the New operator. You'd see something like this:

Dim myObj As Object

myObj = New Object()

You can also do it inline: Dim myObj As Object = New Object()

When you try to do that with your PaintEventArgs, you'll see that that's quite impossible. PaintEventArgs requires information that's taken from a Windows Form control. That method you've written needs to handle an event. This post is too long as it is, so hopefully someone else can explain events and how they're related to methods. Basically, each control (textbox, image, or even the picture itself) raises an event every time it "paints" to the screen. You can "handle" that event; or do actions when it occurs, by doing this:

Public Sub OnPaint(sender as Object, e as PaintEventArgs) Handles myControl.OnPaint

You are declaring that whenever myControl raises an event for OnPaint, it will call this method, with arguments provided from the control. You cannot simply substitute the required arguments from elsewhere. In order for it to work properly, the event arguments must be passed from the control that you wish to paint to.

I hope this helps. Please let me know if I've been unclear.

Upvotes: 0

SLaks
SLaks

Reputation: 887519

You can't do that.

Instead, handle the Paint event and draw everything you need to.

To trigger a redraw, call Invalidate().

Upvotes: 3

Related Questions