Как реагировать на события для объектов в массиве

Я сделал массив плиток (картинных блоков) в массиве, и мне нужно, чтобы они все что-то делали при нажатии, но не знаю, как это сделать. В частности, я хочу иметь возможность разместить на них какой-либо другой объект, щелкнув плитку и заставив этот объект перейти в местоположение этой плитки. Я знаю, что вы можете предложить взглянуть на переменную mouseposition и создать невидимую рамку над всеми плитками для регистрации кликов, но я хотел бы знать, как зарегистрировать любое событие для объекта в массиве для всего, что появится в будущем. Кстати, я знаю, как регистрировать события для объектов, которых нет в массиве. Объект, который я хочу переместить поверх изображения, также будет из массива объектов, но другого.

Вот мой код:

Public Class Form1
    Dim tiles(50) As PictureBox 'This is the object array of tiles
    Dim plants() As String 'I haven't set this up yet, but this will be for the objects to be 'placed' on the pictureboxes.

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim tileWidth As Integer = 50
        Dim tileHeight As Integer = 50
        Dim xindent As Integer = 10
        Dim yindent As Integer = 10
        For x = 0 To 9
            For y = 0 To 4
                ReDim Preserve tiles(x * y)
                tiles(x * y) = New PictureBox With {.Visible = True, .Size = New System.Drawing.Size(50, 50), .Parent = Me, .BackColor = Color.GreenYellow, .Image = Nothing}
                tiles(x * y).Location = New System.Drawing.Point(x * tileWidth + xindent, y * tileHeight + yindent)
                If (x Mod 2 = 0 And y Mod 2 = 0) Or (x Mod 2 <> 0 And y Mod 2 <> 0) Then
                    tiles(x * y).BackColor = Color.Green
                End If
            Next
        Next
    End Sub
End Class

Я просто не знаю, как настроить обработчик события клика для массива плиток, поэтому его нет в приведенном выше коде.

Заранее спасибо за вашу помощь.


person TeeMee123    schedule 11.12.2014    source источник
comment
msdn.microsoft.com/en-us/library/7taxzxka.aspx   -  person Ňɏssa Pøngjǣrdenlarp    schedule 11.12.2014


Ответы (2)


Для этого существует AddHandler. После New нужно просто прикрепить функцию к событию

AddHandler tiles(x * y).Click, AddressOf Tile_Click

И есть функция, которая обрабатывает событие

Private Sub Tile_Click(sender As Object, e As System.EventArgs)

    ' sender represent the reference to the picture box that was clicked

End Sub

Если вы уже знаете размер массива, вам следует изменить размер массива только один раз, а не каждый раз, когда вы зацикливаетесь (переместите ReDim из циклов). Кроме того, поскольку y равен 0 в первом цикле, вы в основном выполняете ReDim из 0 элементов (x * y = 0, когда y = 0)

person the_lotus    schedule 11.12.2014
comment
Спасибо, теперь это имеет больше смысла. Тем не менее, я не совсем уверен, что вы имели в виду под повторным затемнением 0 элементов, поскольку я использовал материал в скобках в качестве индекса объекта, который нужно настроить, а не количество объектов, которые нужно настроить. - person TeeMee123; 11.12.2014
comment
@ TeeMee123 Посмотрите на первый проход в вашем цикле (x = 0, y = 0). Когда вы умножаете их вместе, получается 0 (уменьшите длину массива, и вы создадите новый элемент с индексом 0). Теперь на втором проходе (x = 0, y = 1). Когда вы умножаете x * y = 0 * 1, это также будет 0. То же самое для вашего второго прохода (x = 0, y = 2). - person the_lotus; 11.12.2014
comment
@TeeMee123 Когда (x = 1, y = 2) будет создано новое изображение с индексом 2 (xy = 1*2 = 2). Но тогда у вас возникнет проблема, когда (x = 2, y = 1), поскольку умножение тогда приведет к 2 (xy = 2*1 = 2). - person the_lotus; 11.12.2014

the_lotus уже дал вам отличный ответ.

Просто хотел поделиться трюком, который я часто использую при подключении событий с помощью AddHandler.

Объявите временную переменную, используя WithEvents в своем классе:

Public Class Form1

    Private WithEvents Tile As PictureBox

    ...

Теперь в двух раскрывающихся списках в верхней части редактора кода измените Form1 на Tile и (Declarations) на Click (или любое другое событие, которое вы хотите). Это введет для вас метод с правильной подписью метода:

Private Sub Tile_Click(sender As Object, e As EventArgs) Handles Tile.Click

End Sub

Удалите часть Handles Tile.Click, которая появляется в конце первой строки:

Private Sub Tile_Click(sender As Object, e As EventArgs) 

End Sub

Наконец, удалите свое временное объявление, в котором использовалось WithEvents.

Теперь у вас есть метод с правильной подписью, который вы можете использовать с AddHandler. Это очень удобно для событий, которые не имеют стандартной подписи.

person Idle_Mind    schedule 11.12.2014