0

I'm having a trouble with VB.NET:

I've got 3 different Forms (Public Class): mainForm, plotForm and tradeForm.

Both plotForm and tradeForm call a sub which is part of mainForm, called SendHost:

Public Class mainForm
    Public Sub SendHost(Text As String)
        Dim OutData() As Byte = Encoding.Unicode.GetBytes(Text)
        Client.BeginSend(OutData, 0, OutData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSend), Client)
    End Sub
End Class

When calling from plotForm, there's no problem at all:

Public Class plotForm
    Private Sub btnBuy_Click(sender As Object, e As EventArgs) Handles btnBuy.Click
        mainForm.SendHost("GBuy§" & Prop.PositionID)
        ''' Another code here....    
    End Sub
End Class

However, when the same sub is called from another sub called Trade, there is a problem:

Public Class tradeForm
    Private Sub Trade(sender As Object, e As EventArgs) Handles btnTrade.Click
        btnTrade.Enabled = False
        mainForm.SendHost("GATS§" & ID)
        'More code here...
        Me.Close()
    End Sub
End Class

This will start the sub in mainForm, but Visual Studio tells me that "Client" is Null, giving me a NullReferenceExpection. This doesn't happen with btnBuy_Click. I dont understand this, and any hints to a solution are very welcome! Thank you! Feel free to ask anything.

plotForm and tradeForm are started like (in mainForm, different subs):

Dim TradeW As New Trade
TradeW.ShowDialog(Me)

and:

Dim plotbox As New PlotBox
plotbox.ShowDialog(Me)
Ikx_1
  • 1
  • 2
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Enigmativity Jul 12 '16 at 04:40
  • You hint is, "where is `Client` instantiated?" – Enigmativity Jul 12 '16 at 04:42
  • Client is part of mainForm, Initialized at beginging of it. Dim Client As Socket It's connected to remote host and begins sending data at the SendHost sub. – Ikx_1 Jul 12 '16 at 04:48
  • Clearly `Client` isn't being instantiated, but you haven't posted the code that shows how it is so we can't help. You need a [mcve]. – Enigmativity Jul 12 '16 at 04:54
  • Also both of those subs are ran only after the connection is made to the server via the same client (nothing changed) – Ikx_1 Jul 12 '16 at 04:54
  • Here's full mainForm: http://paste.ofcode.org/HAFU4UKk25ES5mmHNDk8FH Here's full plotForm: http://paste.ofcode.org/DpVTqqXPncaBrT7TFYqWjW Here's full tradeForm: http://paste.ofcode.org/g5Q5hcNpG2nqJzaiqmxfnL Hopefully this gives us a clue – Ikx_1 Jul 12 '16 at 04:58
  • There appears to be only one place in the `mainForm` that `Client` is instantiated. And it is done in button click event. So now we need to find out all the places that `mainForm` is instantiated. Or are you using the default instance? – Enigmativity Jul 12 '16 at 06:03
  • Yes I believe so. Im so sorry for disturbing you this much, I really appreciate your help! :D If this helps, heres the whole project here: https://1drv.ms/u/s!AoMbdmwE9zfGdiyXV3GThgg74kg – Ikx_1 Jul 12 '16 at 06:41
  • Yeah, your problem is that you're using the default instance of your main form. You need to explicitly declare and pass the reference to `mainForm` around the place. – Enigmativity Jul 12 '16 at 11:54
  • You're also doing some weird stuff like `Dim tradew As New Trade With {.IncomingTrade = False, .PlotList = PlotList, .PlayerList = PlayerList, .ImHost = ImHost}`. That just makes you expose more stuff than you need. You should incorporate that stuff into the constructor to allow the components to be encapsulated. – Enigmativity Jul 12 '16 at 11:55

1 Answers1

0

I think your main problem was that somewhere you were picking up the wrong (or new instance) of mainForm. You're using the shared instance of mainForm which is a wholly bad idea. I don't know why that feature was ever introduced to VB.NET - it just leads to bugs like this.

I ended up downloading your project and basically manually renamed the class mainForm to mainFormClass and then introduced this code throughout your classes until your project compiled:

Dim mainForm As mainFormClass

Public Sub New(mainForm As mainFormClass)

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

    Me.mainForm = mainForm

End Sub

I had to then change the instantiation of each form to be like Dim propW As New PlotBox(Me.mainForm) or Dim plotbox As New PlotBox(Me) depending where the class was made.

I got it all to compile, but I couldn't determine if your bug was resolved, but I assume that it was.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172