Class properties, methods and events
This topic covers properties, methods and events that you can add to classes.
Property overview
A Property is a trait that tells you something about an object. You use them as a way for class instances to store or calculate values. You can add four types of properties to classes: properties, computed properties, shared properties and shared computed properties.
You can add properties to a subclass to store values that its super class doesn't store. For example, you might want to create a subclass of the TextField control that stores the last value the user entered. This would allow you to selectively reject the current entry and restore the last entry.
Learn more about Properties and Computed properties in the Properties topic.
Properties
Properties are variables that belong to an entire class instance rather than just a single method. To add a property to a class, use the Add button on the Code Editor toolbar, Insert > Property from the menu, the contextual menu or the keyboard shortcut (Option Command P on macOS or Ctrl Shift P on Windows and Linux). You can set the property name, type, default value and scope using the Inspector.
To quickly create a property, you can enter both its name and type on one line in the Name field like this: PropertyName As DataType. When you leave the field, the type will be set in the Type field.
Properties added in this manner are sometimes called Instance Properties because they can only be used with an instance of the class. You can also add computed properties to a class. These are properties whose values are calculated rather than stored.
Method overview
Methods provide functionality for your classes. They usually perform some action, such as loading data or calculating values.
Learn more about Methods in the Methods topic.
Methods
Methods (Instance Methods) are methods that belong to a class instance.
Scope of items
Items on a class, such as method or properties must have a scope defined. The scope indicates where the property can be used. You set the Scope using the Inspector for the item. There are three choices:
Public: Can be used anywhere in your code with no restrictions, either within the class or from any class instance. To access the item within the class, refer to it by its name. For example, to use a property or method in a class instance, use dot notation:
MyClassInstance.MyProperty = value
MyClassInstance.MyMethod
Protected: Can be used by the class in which it is contained and any subclasses. To access the item, refer to it by its name.
Private: Can be used only by the class in which it is contained. To access the item, refer to it by its name.
Refer to Encapsulation for more on scope.
Events
Events are a type of method that is called by some action (or event) that has occurred. These events have nothing to do with the “events” in “event-driven programming”. Many classes and controls have their own built-in events (which are covered in the User Interface and Framework books), but you can also create your own events using Event Definitions.
You do not directly call event handlers in your own code. For example, if you find that you need to manually call the Pressed event of a button, then you should instead put the code you need to call in a method. You can have the Pressed event handler call the method and you can now call the method directly in your own code as needed.
Event definitions
Event Definitions gives you a way to add your own Event Handlers to subclasses. Event Definitions can be called only from the class itself, but they can be implemented as an Event Handler only by its subclasses. To add an event definition to a class, use the Add button on the Code Editor toolbar, Insert > Event Definition from the menu or the contextual menu. With an event definition in place, you can then implement the event using Add Event Handler on a subclass or when you add this class to a layout.
For example, say you have a Save method on a class and decide that you should give subclasses a way to do processing before and after the save. One way you could do this is by overriding the Save method on the subclass like this:
Sub Save
PreSave
Super.Save
PostSave
End Sub
This works but it relies on you defining and implementing everything properly. If you forget to call Super.Save then your overridden method won't actually save! But if you do this with events, then there is no room for error. With events, you create two event definitions on the super class: PreSave and PostSave. In the Save method on the super class, you then call PreSave at the beginning and PostSave at the end. When you create a subclass, you will see that it has two Event Handlers you can add to it: PreSave and PostSave. Add those event handlers and implement them as needed. Since you are not overridden the Save method, your code circumvents the possible issue shown above.
The built-in control classes all contain a wide variety of event handlers (such as Opening), all of which work in this manner.
Note that when you implement an event handler, it no longer appears in subclasses. If you want the event handler to still be available to additional subclasses, you need to create a new event definition in the subclass (matching the name and parameters) and then call it in from event handler you implemented. You can easily add a matching event definition by right-clicking on the event you have implemented and choosing "Create Event Definition from Event".
When you create an event definition, you can enter a description for it in the Description field on the Advanced (gear) tab of the Inspector. This description appears in the Add Event Handler window when the event is selected.
Animal example
Looking back at the Animal example that was done using Inheritance with method overriding, this is how you would do it using events.
Create a new class called Animal. Add to it a Speak method that returns String with this code:
Return SpeakSound
Now add to the Animal class an Event Definition called SpeakSound and set its return value to String.
Next, create a subclass of Animal, called Cat. Click on the button “+” button on the toolbar and select “Add Event Handler”. In the dialog, you will see the SpeakSound event handler. Select and and press OK. The code for this event handler is:
Return "Meow!"
Create another subclass of Animal, called Dog, and also add the SpeakSound event handler with this code:
Return "Woof!"
To test this, create a button on a window. In the Pressed event of the button add code to create an array of Animals:
Var animals() As Animal
animals.AddRow(New Cat)
animals.AddRow(New Dog)
For Each a As Animal In animals
MessageBox(a.Speak)
Next
When you run this code, you will see “Meow!” and then “Woof!”.
Because Cat and Dog are both subclasses of Animal, they are allowed to be assigned to a variable (the animals array) with a type of Animal. When you call the Speak method of Animal (in the loop), it in turn calls the SpeakSound event handler of each subclass that was added to the array.
AddHandler
The AddHandler command is used to have a method on one object handle the processing of an event on another. This is often used to allow you to instantiate a class directly and implement its event without having to create a separate subclass.
For example, if you want to implement the Run event of a Timer, you will typically create a subclass. This can be done by dragging a Timer onto your window or web page or by adding a Timer subclass to your project and using that instead.
Alternatively, you can declare the Timer in your code and then use AddHandler to have the Action event handled by a method on your window. For example:
Var t As New Timer
AddHandler t.Run, AddressOf MyTimerMethod
t.RunMode = Timer.RunModes.Multiple
t.Period = 500
t.Enabled = True
In order for this to work, you must have a method in the window called MyTimerMethod and it must have a parameter for the timer itself:
Sub MyTimerMethod(t As Timer)
' Your code goes here
End Sub
If the event you are handling has additional parameters, include them after the initial parameter used for the class itself. AddHandler can also be used in this manner for Threads:
Var t As New Thread
AddHandler t.Run, AddressOf MyThreadMethod t.Run
See also
Me vs Self topic