Вероятно, вы столкнетесь с MemoryOverflowException с этим дизайном. Судя по всему, вы, вероятно, пытаетесь сделать какую-то карту, если это так, тогда этот ответ для вас (в противном случае просто проигнорируйте ее).
На высоком уровне вы должны только создать количество элементов управления PictureBox, которые могут поместиться на экране в любой момент времени. Вы можете рассчитать это с помощью следующей функции:
Private Function CalculateSizeToFitParent(ByVal parent As Control, ByVal childSize As Size) As Size
Return New Size(parent.Width \ childSize.Width, parent.Height \ childSize.Height)
End Sub
Вы бы реализовали это так, чтобы создать PictureBox для заполнения видимой области текущей формы:
Dim pictureBoxSize As Size = New Size(8, 8)
Dim visibleArea(pictureBoxSize.Width - 1, pictureBoxSize.Height - 1) As PictureBox
Dim numberOfPictureBoxes As Size = CalculateSizeToFitParent(Me, pictureBoxSize)
For x As Integer = 0 To numberOfPictureBoxes.Width - 1
For y As Integer = 0 To numberOfPictureBoxes.Height - 1
visibleArea(x, y) = New PictureBox() With {
.Location = New Point(x * pictureBoxSize.Width, y * pictureBoxSize.Height)
.Size = pictureBoxSize
}
Me.Controls.Add(visibleArea(x, y))
Next
Next
Следующая часть состоит из двух частей:
- Вам необходимо следить за тем, где находится верхний левый угол текущего видимого элемента
- Вам необходимо будет перезагрузить изображения в соответствующем визуальном элементе. Площадь карты.
Это предполагает, что у вас есть 2D-массив, в котором хранятся ваши изображения. И обратите внимание, что вы не воссоздаете элементы управления PictureBox, а просто перезагружаете изображение существующего элемента управления:
Private _currentLocation As Point = New Point(0, 0) ' If you're starting somewhere else change it here
Public Property CurrentLocation As Point
Get
Return _currentLocation
End Get
Set(ByVal value As Point)
If (value <> _currentLocation) Then
_currentLocation = value
Me.OnCurrentLocationChanged()
End If
End Set
End Property
Protected Overridable Sub OnCurrentLocationChanged()
RaiseEvent CurrentLocationChanged(Me, EventArgs.Empty)
End Sub
Public Event CurrentLocationChanged(ByVal sender As Object, ByVal e As EventArgs)
Private Sub MyForm_CurrentLocationChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.CurrentLocationChanged
If (visibleArea Is Nothing) Then
Throw New Exception("The visible area has not been generated yet.")
End If
If (_currentLocation Is Nothing) Then
Throw New Exception("The CurrentLocation cannot be null.")
End If
Dim widthUpperBounds As Integer = My2DArrayOfImageLocations.GetUpperBounds(0) - 1
Dim heightUpperBounds As Integer = My2DArrayOfImageLocations.GetUpperBounds(1) - 1
For x As Integer = 0 To visibleArea.GetUpperBounds(0) - 1
For y As Integer = 0 To visibleArea.GetUpperBounds(1) - 1
If (x + _currentLocation.Width > widthUpperBounds OrElse y + _currentLocation.Height) Then
'This "block" is outside the view area (display a blank tile?)
Else
visibleArea(x, y).Load(My2DArrayOfImageLocations(x + _currentLocation.Width, y + _currentLocation.Height))
End If
Next
Next
End Sub
Теперь при каждом сбросе свойства CurrentLocation (как бы вы это ни делали, например, стрелка). ключи, asdw и т. д. c.) он перерисовает видимую область карты.
Обновление Обратите внимание, что я "напечатал" этот пример, и вам, возможно, потребуется настроить это немного. После некоторых размышлений вам, вероятно, также понадобится вызвать метод Refre sh PictureBox при загрузке изображения (я не тестировал).