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("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
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
在下面的代码中,我试图更改在数组 '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("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
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