VB.NET |面板中的图片框数组:未将对象引用设置为对象的实例

VB.NET | Array of pictureboxes in panel: Object reference not set to an instance of an object

在下面的代码中,我试图更改在数组 'pictureboxes(9, 9)' 中创建的现有控件的标签。当我尝试这样做时,出现错误 'Object reference not set to an instance of an object.'。这是在 checkdata 子代码中完成的,靠近代码底部,注释为“对象引用未设置为对象的实例。'。

传递给子程序的字符串是一长串数字,如果有帮助,图片框会被放入布局面板中。

我明白这个错误是什么意思,我知道 pictureboxes(i, j) 在断点时 = nothing;我只是不知道如何修复它:s

非常感谢任何帮助,希望我能尽快回答任何问题 comments/answers。

谢谢

Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.Net

Public Class Form1
'0 as default tile, 1 as clicked, 3 as set mine (host perspective)
Dim tiles() As Integer = {0}
Public pictureboxes(9, 9) As PictureBox
Dim flagged() As Integer
Dim clicked As Integer()
Dim columns As Integer = 10
Dim rows As Integer = 10
Dim placedMinesCount As Integer = 0
Dim formattedTag As String()
Public turn As Boolean = False
Dim stringToSend As String

Public Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For i As Byte = 0 To 9
        For j As Byte = 0 To 9

            pictureboxes(i, j) = New PictureBox
            pictureboxes(i, j).Height = 60
            pictureboxes(i, j).Width = 60
            pictureboxes(i, j).ImageLocation = "0.png"
            pictureboxes(i, j).Tag = "0|" & i & ", " & j

            AddHandler pictureboxes(i, j).Click, AddressOf Tile_Click

            Dim column As Integer = j
            Dim row As Integer = i

            Panel.Controls.Add(pictureboxes(i, j), column, row)

        Next
    Next

    If Login.isHost = True Then
        Me.Text = "Set your mines (10)"
        turn = True
    ElseIf Login.isHost = False Then
        Me.Text = "Await your turn"
        btnEndTurn.Visible = False
        btnEndTurn.Enabled = False
    End If
End Sub

Protected Sub Tile_Click(ByVal sender As Object, ByVal e As EventArgs)
    formatSenderTag(sender.tag)
    If Login.isHost = True Then
        Dim clickAction As String = formattedTag(0)

        Select Case clickAction
            Case "0"
                If placedMinesCount < 10 Then
                    placedMinesCount = placedMinesCount + 1
                    sender.imagelocation = "3.png"
                    sender.tag = "3"
                    Me.Text = "Set your mines (" & 10 - placedMinesCount & ")"

                ElseIf placedMinesCount >= 10 Then
                    MsgBox("You have placed all of your 10 Mines")
                End If
            Case "2"
                MsgBox("You cannot set a mine here")
            Case "3"
                placedMinesCount = placedMinesCount - 1
                Me.Text = "Set your mines (" & 10 - placedMinesCount & ")"
                sender.imagelocation = "0.png"
                sender.tag = "0"
        End Select


    ElseIf Login.isHost = False Then
        Dim clickAction As String = formattedTag(0)
        Select Case clickAction
            Case "0"
                sender.tag = "1"
                sender.imagelocation = "1.png"
            Case "3"
                MsgBox("Game Over")
            Case "2"
                MsgBox("Already Clicked")
        End Select
    End If
End Sub

Private Sub formatSenderTag(ByVal sender As String)
    'split into array 
    'element 0 as TILE TYPE
    'element 1 as TILE LOCATION
    formattedTag = sender.Split(New String() {"|"}, StringSplitOptions.None)
End Sub

Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    End
End Sub

Private Sub btnEndTurn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEndTurn.Click
    turn = False

    gridtostring()
    senddata()
End Sub

Private Sub gridtostring()
    For i As Byte = 0 To 9
        For j As Byte = 0 To 9
            formatSenderTag(pictureboxes(i, j).Tag & "|")
            stringToSend = stringToSend & formattedTag(0)
        Next
    Next
End Sub

Private Sub senddata()
    '***SEND STUFF
    'Assuming you have a textbox with the data you want to send
    If (Not String.IsNullOrEmpty(stringToSend)) Then
        Dim data() As Byte = Encoding.ASCII.GetBytes(stringToSend)
        Login.sendingClient.Send(data, data.Length)
    End If
End Sub

Public Sub checkdata(ByVal data As String)
    If Not data = stringToSend Then
        'Dim loopcount As Integer = 0
        For i As Byte = 0 To 9
            For j As Byte = 0 To 9
                Dim loopcount As Integer = (i.ToString & j.ToString) + 1
                'Dim pineapple As String = pictureboxes(i, j).Tag
                'pictureboxes(i, j).Tag = GetChar(data, 3)

                pictureboxes(i, j).Tag = GetChar(data, loopcount) & "|" & i & ", " & j '***Object reference not set to an instance of an object.***
                formatSenderTag(pictureboxes(i, j).Tag)
                pictureboxes(i, j).ImageLocation = formattedTag(0)
                pictureboxes(i, j).ImageLocation = "0.png"
                'Panel.Controls(pictureboxes(i, j).Tag) = GetChar(data, 3) '.Tag = GetChar(data, 3)

            Next
        Next
    End If
End Sub
End Class

***下面是调用 CHECKDATA() 的其他表单

Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.Net

Public Class Login

Dim Port As Integer = 8123
Private Const broadcastAddress As String = "255.255.255.255"
Public receivingClient As UdpClient
Public sendingClient As UdpClient
Dim sendAddress As String
Dim ServerMode As Boolean = False
Public isHost As Boolean = true
Dim returndata As String

Private Sub Login_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

End Sub

Private Sub ComboWANLAN_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboWANLAN.SelectedIndexChanged
    If ComboWANLAN.Text = "Online (WAN)" Then
        txtSendAddress.Enabled = True
    ElseIf ComboWANLAN.Text = "Offline (LAN)" Then
        txtSendAddress.Enabled = False
    End If
End Sub

Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
    '***START PORT LISTENING/SENDING AND NETWORKING STUFFS
    Port = txtPort.Text
    InitializeSender()
    InitializeReceiver()

End Sub

Private Sub btnHost_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHost.Click
    '***START PORT LISTENING/SENDING AND NETWORKING STUFFS
    Port = txtPort.Text
    InitializeSender()
    InitializeReceiver()
    isHost = True
    Me.Hide()
    Form1.Show()
End Sub

Private Sub InitializeSender()
    If ComboWANLAN.Text = "Offline (LAN)" Then
        sendingClient = New UdpClient(broadcastAddress, Port)
        'Use broadcastAddress for sending data locally (on LAN), otherwise you'll need the public (or global) IP address of the machine that you want to send your data to
    ElseIf ComboWANLAN.Text = "Online (WAN)" Then
        sendAddress = txtSendAddress.Text
        sendingClient = New UdpClient(sendAddress, Port)
        'Use broadcastAddress for sending data locally (on LAN), otherwise you'll need the public (or global) IP address of the machine that you want to send your data to
    End If
    sendingClient.EnableBroadcast = True
End Sub

Private Sub InitializeReceiver()
    receivingClient = New UdpClient(Port)
    ThreadPool.QueueUserWorkItem(AddressOf Receiver) 'Start listener on another thread
End Sub

Private Sub Receiver()
    Dim endPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, port) 'Listen for incoming data from any IP on the specified port
    Do While True 'Notice that i've setup an infinite loop to continually listen for incoming data
        Dim data() As Byte
        data = receivingClient.Receive(endPoint)
        If Form1.turn = False Then
            returndata = Encoding.ASCII.GetString(data) 'Recived data as string
            Form1.checkdata(returndata)
        End If
    Loop
End Sub

Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    End
End Sub
End Class

***堆栈跟踪

   at Minesweeper.Form1.checkdata(String data) in                c:\users\harry\documents\visual studio     2010\Projects\Minesweeper\Minesweeper\Form1.vb:line 139
   at Minesweeper.Login.Receiver() in C:\Users\Harry\Documents\Visual Studio     2010\Projects\Minesweeper\Minesweeper\Login.vb:line 71
   at Minesweeper.Login._Lambda$__1(Object a0) in C:\Users\Harry\Documents\Visual Studio 2010\Projects\Minesweeper\Minesweeper\Login.vb:line 61
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

注意:有些地方的间距搞砸了

这段代码没有给出你提供的数据的错误:

checkdata("00000000000000000000000000000000000000000000000000000000000000000000000000000000‌​00000000000000000000")

Public Sub checkdata(ByVal data As String)
    If Not data = stringToSend Then
        'Dim loopcount As Integer = 0
        For i As Byte = 0 To 9
            For j As Byte = 0 To 9
                Dim loopcount As Integer = (i.ToString & j.ToString) + 1
                'Dim pineapple As String = pictureboxes(i, j).Tag
                'pictureboxes(i, j).Tag = GetChar(data, 3)

                pictureboxes(i, j).Tag = GetChar(data, loopcount) & "|" & i & ", " & j '***Object reference not set to an instance of an object.***
                formatSenderTag(pictureboxes(i, j).Tag)
                pictureboxes(i, j).ImageLocation = formattedTag(0)
                pictureboxes(i, j).ImageLocation = "0.png"
                'Panel.Controls(pictureboxes(i, j).Tag) = GetChar(data, 3) '.Tag = GetChar(data, 3)

            Next
        Next
    End If
End Sub

查看您的堆栈跟踪和代码,您在登录中缺少 Form1 的实例化 class。我认为这可能是问题所在。

尝试将此添加到登录名的开头 class:

Dim Form1 as New Form1