Most of the time when we talk about events the first thing that pops into someones head isa UI control and the events is has for interaction with the user. A pushbuttons Action (or Pressed) event for instance. Or the various events on listboxes for selecting rows, handling mouse clicks, keyboard events and the myriad of other user interface and interaction related things listboxes handle.
But thats not the only way to use events 🙂
Sometimes you may write a control and it needs to get data from the layout its on or from something else outside its control. So how do you get access to this ?
You could, as I’ve seen in some code, make everything PUBLIC and then the specific control just gets its parent control and grabs what ever property or calls whatever parent method it needs.
This is, IMHO, a bad practice as it makes your code more fragile since a change in the method or property you’re accessing this way could cause unrelated code to break. And because it destroys any encapsulation you might have created. Its a huge violation of the Law Of Demeter I wrote about before. You should only use things that are passed to you as parameters, that you own and control, or that are declared in your code. Reaching way outside to the parent control would definitely violate this principle.
So what can you do ?
As discussed before, subclasses CAN create NEW events and you could use an event to ask the containing layout for whatever property value or reference to something else the layout has access to.
We’ll create a small project to demonstrate the idea. What we will have is a custom canvas control that will ask the outside world for the color that it should draw itself as. You might normally do this as a simple property but I am NOT going do that to demonstrate. The other thing we will have on the layout is yet another custom canvas that acts simply as a color picker.
I’m using 2019r1.1 so some things may be different if your using a newer version
First start a new desktop project
Add a new subclass of Canvas by dragging the canvas control from the Library over to the Navigator (or you can add a new class and set its super to Canvas in the inspector). Name this new class ColorSelectorSwatch.
Add a public property called FillColor as Color
We’ll add the MouseUp event handler and put the following code in it
Dim c As Color If SelectColor(c, "Select a color") Then Me.FillColor = c Me.Invalidate RaiseEvent Updated End If
Also add the Mouse Down event handler and put this code in it
Also add a new Event Definition and name it Updated
Thats it for our little color selector swatch
Add an instance of our ColorselectorSwatch to the default layout, Window1, by dragging it from the Navigator on to the layout Window1. By default its name will be ColorSelectorSwatch1
Add the event handler for the new Updated event. We’re not going to put any code in it just yet. We’ll return to this later once we create our other custom control.
Now add another canvas subclass to your project. Again you can do this by dragging or by simply adding a class and changing the superclass in the inspector. Name this class CustomCanvas. This is the one we’re going to add the event to that will ask the outside world what color it should draw itself in.
Add the Event handler for the Paint event to the CustomCanvas.
Also add a new event definition colorToDrawWith() As color.
Note that this event handler has a return value that is a color. When we need to get the color we’ll raise this event, get whatever return value, and then paint our canvas with this color. *
The code for the Paint event is fairly simple
Dim c As Color c = RaiseEvent ColorToDrawWith // call the event to get the color // from the outside world g.ForeColor = c g.FillRect 0,0, g.width, g.height
Drag an instance of this custom canvas onto the default window and make sure it does not overlap your other canvas. By default it will be named CustomCanvas1.
Now we’ll add the handler for the ColorToDrawWith event. All we need is one line
Now return to the Updated event of ColorSelectorSwatch1. In there we need one line to make it so our CustomCanvas will know to redraw itself when the color selector swatch gets a new color selected. In the Updated event put
And run. Every time you select a new color in the color swatch the other canvas will update and redraw itself. And, to do so we have used an event to return information to the control instance that tells it what color to draw with.
Here’s my completed sample
*Of note one of the things that got added in versions after 2019r1.1 is a way to tell IF the event is implemented. You could use this to know whether you should redraw with the color returned or not.
The only change would be to make the Paint event of CustomCanvas read as follows
If IsEventImplemented("ColorToDrawWith") Then Dim c As Color c = RaiseEvent colorToDrawWith g.ForeColor = c g.FillRect 0,0, g.width, g.height End If