NullReferenceException on Dynamic UserControl

Mercaton

Newcomer
Joined
Aug 30, 2009
Hi

I can't figure out why this is happening. The app throws a nullreferenceexception on Me.Controls.Add(tab(count)).

Code:
Public tab As Tab()
Public wb As WebBrowser()
Public count As Integer = 0

Public Sub NewTab(ByVal url As String)
    Try
        wb(count) = New WebBrowser
        tab(count) = New Tab

        wb(count).Name = "wb" & count.ToString()
        wb(count).Location = New Point(0, 69)
        wb(count).Size = New Size(903, 517)
        wb(count).Navigate(url)

        tab(count).Name = "tab" & count.ToString()
        If (count > 1) Then tab(count).Size = tab(count - 1).Size
        If (count = 0) Then tab(count).Size = New Size(212, 32)
        If (count > 1) Then tab(count).Location = New Point(tab(count - 1).Location.X + 212, tab(count - 1).Location.Y)
        If (count = 0) Then tab(count).Location = New Point(120, 0)

        Me.Controls.Add(wb(count))
        Me.Controls.Add(tab(count))

        count = count + 1
    Catch ex As Exception
        MessageBox.Show(ex.Message())
    End Try
End Sub

tab() is the name of the array of the usercontrols which has just a label and 2 pictureboxes in it.

I know what the error means just not sure why it's doing this. Any tips?

Thanks
 

orca44

Freshman
Joined
Dec 31, 2004
Location
Cape Town, South Africa
I recreated the snippet on my side without the WebBrowser and couldn't reproduce the error. What happens if you run the code without the WebBrowser segment?
Where do you dimension the tab() array?
 

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Location
USA
orca may be right, in the code you've posted you don't actually create the array. Might I suggest you ditch the array and go with the nifty List(Of T) class. It's a rare case these days that a collection class doesn't make things simpler.

There are some other things I might have done differently, as well. These are only suggestions (except for the Exception issue, which is a very strong suggestion). Take em or leave em.
Code:
Public tabs As New [COLOR="Blue"]List(Of Tab)[/COLOR]
Public wbs As New [COLOR="Blue"]List(Of WebBrowser)[/COLOR]

Public Sub NewTab(ByVal url As String)
    Try
        [COLOR="Blue"]Dim newWb As New WebBrowser
        Dim newTab As New Tab[/COLOR]

        newWb.Name = "wb" & count.ToString()
        newWb.Location = New Point(0, 69)
        newWb.Size = New Size(903, 517)
        newWb.Navigate(url)

        newTab.Name = "tab" & count.ToString()

        [COLOR="Blue"]Dim IsFirstTab As Boolean = tabs.Count = 0[/COLOR]
        If (IsFirstTab) Then 
            newTab.Size = New Size(212, 32)
            newTab.Location = New Point(120, 0)
        Else
            newTab.Size = tab(count - 1).Size
            newTab.Location = New Point(tab(count - 1).Location.X + 212, tab(count - 1).Location.Y)
        End If

[COLOR="Blue"]        wbs.Add(newWb)
        tabs.Add(newTab)
[/COLOR]        
        Me.Controls.Add(newWb)
        Me.Controls.Add(newTab)
    
    Catch ex As Exception
[COLOR="Blue"]        ' Bad plan, man. You only want to capture exceptions you are prepared to handle.
        ' You should make a point of NOT catching things like OutOfMemoryException.
[/COLOR]        MessageBox.Show(ex.Message())
    End Try
End Sub
 

Mercaton

Newcomer
Joined
Aug 30, 2009
Thanks for the replies!

Funny, I think you may be right. Bit of research and found I am essentially declaring and initializing it at the same time. The array with at least one element in it worked fine (which defeats the purpose of the code).

Without the WebBrowser code segment the tab shows up (still throws the exception) but it's at the wrong location. So no go there either.

I think the List will have to do it. Seems to do the job so far.

And yeah, maybe I will handle exceptions a bit better, just think it's better than having the whole thing crash.

Thanks
 

snarfblam

Ultimate Contributor
Joined
Jun 10, 2003
Location
USA
And yeah, maybe I will handle exceptions a bit better, just think it's better than having the whole thing crash.

I understand the sentiment, but there is a reason that this is discouraged. The idea that an exception is supposed to convey is "an error condition that you aren't expecting and probably can't handle", such as running out of memory.

What you really want is to prevent the conditions that produce an exception. Make sure a file exists before you try to read from it. Sometimes you can't prevent an exception, but you know you can recover from it. For example, I wouldn't expect you to verify an image file is completely valid before creating an Image object from the file, but if the image file is invalid, it would make sense to capture the exception, and probably show the user a message such as "The image file is invalid."

As long as you avoid causing exceptions, and handle the ones you can reasonably expect, any other exceptions represent a situation that you aren't prepared for and probably can't recover from. When you handle an exception, you are saying, "I can fix this," and if you blindly handle all exceptions, you're going to cause more harm than good. That's why so many recommend that your program "fail fast" when an error occurs; something is wrong, and the program doesn't know what it is.

If you insist on handling the error, at least inform the user that an error occurred, and the program may be in an inconsistent state (i.e. all bets are off).
 
Top Bottom