You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建PictureBox数组并使用?代码空引用异常求解

解决PictureBox数组空引用异常及动态创建控件的正确方式

问题原因

  • 你声明的Brickn() As PictureBox只是一个数组变量,未初始化实际的数组实例,此时数组处于Null状态,直接通过索引访问Brickn(NoOfBrick)会触发NullReferenceException。
  • VB.NET中数组必须先通过ReDim指定长度才能使用,你缺失了这一关键步骤。

解决方案:两种实现方式

方式1:使用动态调整长度的数组(ReDim Preserve)

每次添加新控件前,重新调整数组长度并保留已有元素:

Dim brickWidth As Integer = 0
Dim Brickn() As PictureBox  
Dim NoOfBrick As Integer = 0       ' 初始化索引计数

Public Function CreateBrick() As PictureBox
  Dim myBrickn As New PictureBox

  With myBrickn
    .Size = Brick.Size
    .Left = brickWidth
    .Top = 0
    .Image = Brick.Image
    .SizeMode = PictureBoxSizeMode.StretchImage
    .BackColor = Color.Black
  End With

  Return myBrickn
End Function

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
   For i = -75 To Me.Width 
     ' 重新调整数组长度,保留已有元素
     ReDim Preserve Brickn(NoOfBrick)
     Brickn(NoOfBrick) = CreateBrick()
     Me.Controls.Add(Brickn(NoOfBrick))
     brickWidth += 170 
     i += 170          
     NoOfBrick +=1
  Next
End Sub

方式2:使用List(Of PictureBox)(更推荐)

数组长度固定,动态添加元素效率低,List(Of T)支持动态扩容,无需手动调整长度:

Dim brickWidth As Integer = 0
' 直接初始化空的PictureBox列表
Dim Brickn As New List(Of PictureBox)  

Public Function CreateBrick() As PictureBox
  Dim myBrickn As New PictureBox

  With myBrickn
    .Size = Brick.Size
    .Left = brickWidth
    .Top = 0
    .Image = Brick.Image
    .SizeMode = PictureBoxSizeMode.StretchImage
    .BackColor = Color.Black
  End With

  Return myBrickn
End Function

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
   For i = -75 To Me.Width 
     Dim newBrick = CreateBrick()
     Brickn.Add(newBrick) ' 直接添加到列表
     Me.Controls.Add(newBrick)
     brickWidth += 170 
     i += 170          
  Next
End Sub

修正碰撞检测的逻辑问题

你原有的Boll_control_Tick代码存在索引越界风险:NoOfBrick是数组/列表的总数量,而控件索引从0开始,直接用brickn(NoOfBrick)会访问不存在的元素。正确做法是遍历所有砖块检测碰撞:

针对数组的碰撞检测:

Private Sub Boll_control_Tick(sender As Object, e As EventArgs) Handles Boll_control.Tick
  ' 倒序遍历,避免移除元素时索引混乱
  For i = NoOfBrick - 1 To 0 Step -1
    If Ball.Bounds.IntersectsWith(Brickn(i).Bounds) Then
      Me.Controls.Remove(Brickn(i))
      ' 调整数组长度并更新计数
      ReDim Preserve Brickn(NoOfBrick - 2)
      NoOfBrick -= 1
      Exit For ' 单次碰撞仅处理一个砖块,可按需调整
    End If
  Next
End Sub

针对List的碰撞检测(更简洁):

Private Sub Boll_control_Tick(sender As Object, e As EventArgs) Handles Boll_control.Tick
  ' 倒序遍历List,避免移除元素时遍历异常
  For i = Brickn.Count - 1 To 0 Step -1
    Dim brick = Brickn(i)
    If Ball.Bounds.IntersectsWith(brick.Bounds) Then
      Me.Controls.Remove(brick)
      Brickn.RemoveAt(i) ' 直接从List移除元素
      Exit For
    End If
  Next
End Sub

内容的提问来源于stack exchange,提问作者Mr. kismat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:25:36