(Original post by M-AR)
I fixed it . On the form that the grid is on ,I have created a button called "Set Grid".The purpose of this button is to only enable the HandlesMouseDown sub in the MyGridPictureBox class if it is pressed. Is it possible to call a sub that exists in a different class ?
You could do that, but I think it'd be a bit messy. What you're describing here sounds like just remembering whether a button has been pressed (or to put it in programming terms, you're describing a
which is used to change the way your UI behaves).
State is pretty fundamental to writing GUIs; the problem with state is that some kind of state change which might be initiated from one part of the UI is probably important for another part of the UI (as it is in your case here). So for that reason, a very common way to handle state
in a GUI app is to create a completely separate class which only contains properties about the state.
The reason for doing this is that it can get really convoluted to have different Controls talking directly to each other. The neat thing about splitting your app into separate controls is that you can keep them nicely self-contained and things stay fairly simple that way. If those controls start calling methods belonging to other controls then it can make the code get a bit messy, - the controls stop being so self-contained, and after a while you might find out that you've coded yourself up a "spaghetti" GUI.
Obviously there's nothing actually stopping you from having them talk directly to each other, but I'd personally try to avoid it for the sake of my own sanity when trying to trace through the code to see what's actually going on
In your case, the app state class is probably something as simple as:
Public Class MyAppState
Public Property IsDragDropEnabled As Boolean = False
'other app state properties go here in future...
Then all you need to do is create a single instance of MyAppState
in the main form class (i.e. the class where you create all the other PictureBoxes), and pass that instance to all of the PictureBox
instances through their respective New
/ constructor methods (so that the various PictureBoxes can keep a private reference to that 'state' instance...).
(i.e. - Using the 'grid' form example above creating a state instance and passing it to those different PictureBoxes):
Public Class Grid
Private Const Columns As Integer = 8
Private Const Rows As Integer = 8
Private ReadOnly _grid(8, 8) As MyGridPictureBox
Private ReadOnly _state As MyAppState = New MyAppState()
Private Sub Init()
For x = 0 To Columns - 1
For y = 0 To Rows - 1
_grid(x, y) = New MyGridPictureBox(x, y, _state)
Controls.Add(New MyDraggablePictureBox("Fred", 10, 1, _state))
Controls.Add(New MyDraggablePictureBox("Barney", 10, 3, _state))
So, if the draggable PictureBox has also got a private field called _state
that has been picked up from its New
/ constructor method, then within your HandleMouseDown
Subs you can do things like this:
Private Sub HandleMouseDown (sender As Object, args As MouseEventArgs) Handles Me.MouseDown
Which of course would work because Me._state
just refers to a single instance/object in memory belonging to the main form - when one part of the app changes a property on _state, then all the other places which refer to that same object will have access to those exact same properties.
In general, it's not a bad thing to pass references of objects from the main form through a New / constructor method - it's a pretty standard way of getting different parts of your app to talk to each other. Try not to overdo it too much though - you can easily end up creating huge long lists of parameters in a constructor, which can get a bit messy