Paul, this should be much easier in the next release: https://feedback.objo.dev/feature/657
I’ve added a new base class called DesignerComponent for exactly this kind of opt-in designer class. The idea is that a plain opt-in class remains just a plain object, but if your class needs to know which window or container owns it, you make it inherit from DesignerComponent.
How to use it
- Create your class as normal.
- Make it inherit from
DesignerComponent.
- Tick Available in Visual Designer for the class.
- In the Control Library, enable Include Opt-In Classes.
- Drag the class onto the window/container shelf.
- Use the
Attached(owner As Object) event, Me.Owner, or Me.OwnerWindow.
The key difference from passing the window in Window.Opening is timing. Attached fires during designer-generated construction, after Studio has created/added the controls and wired generated event handlers, but before child control Opening events fire.
Example:
Class ControlLabeller Inherits DesignerComponent
Event Attached(owner As Object)
If owner IsA Window Then
AddLabelsToWindow(Window(owner))
ElseIf owner IsA ContainerControl Then
AddLabelsToContainer(ContainerControl(owner))
End If
End Event
Private Sub AddLabelsToWindow(w As Window)
For Each c As Control In w.Controls()
Var label As New Label
label.Text = c.Name
label.Left = c.Left
label.Top = c.Top - 18
label.Width = c.Width
label.Height = 16
w.Add(label)
Next c
End Sub
Private Sub AddLabelsToContainer(container As ContainerControl)
For Each c As Control In container.Controls()
Var label As New Label
label.Text = c.Name
label.Left = c.Left
label.Top = c.Top - 18
label.Width = c.Width
label.Height = 16
container.Add(label)
Next c
End Sub
End Class
For a component placed directly on a window shelf:
Me.Owner # the Window
Me.OwnerWindow # the same Window
For a component placed on a reusable container shelf:
Me.Owner # the ContainerControl
Me.OwnerWindow # may be Nothing during Attached if the container is not in a window yet
So for your case, if the component is intended to inspect or alter controls on the same designer surface, use the owner parameter from Attached. If it is on a window, cast it to Window; if it is on a container, cast it to ContainerControl.
This means you no longer need the Window.Opening workaround just to pass Me into the component.