-1

i am developing a program, which allows you to select seats to reserve in a concert hall by clicking/rolling over a set of pictureboxes, which looks like this like this:

http://postimg.org/image/urhvij3xn/

I know how to make all of these images have roll over effect , but only individually, not as an array.

The closest to a solution i have that allows me to use the same code for all of my pictureboxes is:

 Private Sub ClickImage(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox100.MouseClick, PictureBox101.MouseClick, PictureBox102.MouseClick

But this requires me to enter every single picturebox into the handles area. Is there any way that I can enter an array of pictureboxes into the handles and then use the sender command to detect which one?

Thanks

  • What you want to use is the `AddHandler` keyword. See this for an example : http://stackoverflow.com/a/12672042/327083 Obviously you would need to substitute `PictureBox` for `TextBox` in the example, but the approach is, I think, what you are looking for. – J... Jul 01 '14 at 13:32
  • 3
    This is an elementary Winforms programming task that any introductory book or tutorial will show you how to accomplish. Best way to get started is to find a pair of scissors and cut the mouse umbilical cord so you can no longer drag+drop controls from the toolbox. – Hans Passant Jul 01 '14 at 13:39

1 Answers1

1

The handles syntax is at once a handy feature of VB.NET but also can be a crutch. For simple applications it works ok but, as you have discovered, it is not the most elegant approach for larger projects.

There are a few approaches you could use. What I have suggested in comments is an approach that can be a bit of a hack if you have already worked yourself into a corner. If you're not so far along that you can start with a better approach, then ideally you would be creating your PictureBoxes programmatically rather than dragging and dropping them onto your form at design time. The habit of developing like this tends to create huge messes of code in your application that are difficult to manage. Consider first making a class like :

Private Class ConcertSeat
    Inherits PictureBox
    Private _row As Integer
    Private _column As Integer

    Public Property Row As Integer
        Get
            Return _row
        End Get
        Set(value As Integer)
            _row = value
        End Set
    End Property
    Public Property Column As Integer
        Get
            Return _column
        End Get
        Set(value As Integer)
            _column = value
        End Set
    End Property

    Protected Overrides Sub OnMouseEnter(e As System.EventArgs)
        MyBase.OnMouseEnter(e)
        ' do rollover
    End Sub
    Protected Overrides Sub OnMouseLeave(e As System.EventArgs)
        MyBase.OnMouseLeave(e)
        ' etc
    End Sub
End Class

This is obviously just a skeleton class - you should get the idea. In the class above you would probably want to load and associate the images for the rollovers, etc. Any custom behaviour that will be common to all of the components. If you are incorporating images into your control above you would obviously also want to implement IDisposable to ensure that you clean up the images when the control is disposed.

You can also add properties to identify IsBooked, for example, and even an ID or cross-reference number to link to the person who has booked the seat, etc. The design will have to be up to you - you know the needs better than we do.

Then on your form, without needing to drag and drop anything, simply

Private SeatList As New List(Of ConcertSeat)

Private Sub Form1_Load(sender As Object, e As EventArgs) _
                                               Handles MyBase.Load
    Dim I As Integer
    Dim j As Integer
    Dim newSeat As ConcertSeat
    For I = 0 To 10
        For j = 0 To 10
            newSeat = New ConcertSeat
            newSeat.Row = I
            newSeat.Column = j
            ' AddHandler here does the same job as the Handles clause **!**
            AddHandler newSeat.Click, AddressOf ClickImage
            SeatList.Add(newSeat)
            ' Add Control To Form
            ' Assume here that you have added properties 
            ' to the class that define the xDimension and 
            ' yDimension of the image so that they are laid
            ' out in a grid on your form. 
            newSeat.Top = 10 + newSeat.yDimension * I
            newSeat.Right = 10 + newSeat.xDimension * j
            Me.Controls.Add(newSeat)
        Next
    Next
End Sub

This is a really rough idea, and a somewhat specific one, but it should outline the type of approach that will make your life a lot easier. You don't even have to have the seat inherit from PictureBox - you could keep them separate as a class for data and a class for the image, linked via a Dictionary or something similar.

Also don't forget to unhook the handlers when the form is destroyed :

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) _
                                                Handles MyBase.FormClosing
    For Each seat In SeatList
        RemoveHandler seat.Click, AddressOf ClickImage
    Next
End Sub

Forgetting to unhook handlers can pin objects in memory and prevent the garbage collector from cleaning them up (creating memory leaks).

J...
  • 30,968
  • 6
  • 66
  • 143