Help with adding custom event handler to a containerControl

Hi all,

Grateful for help with this problem…
Instead of using a Xojo pagepanel to navigate the multiple sections of a fairly extensive database app, i’ve decided to parcel off each section as a containerControl and have some data that glues this together in a module. The benefit is that i can parcel off code, control names etc that may conflict in to the containers and deal with them as a separate entity from the main window - the pagepanel way was becoming too unwieldy.

This works really quite well, but it’s trickier when a message needs to go from the container to the app for some other action. In order to do this, I use custom events but not entirely happy with the way I’ve implemented this:

  • in my container control class, i create the event definition
  • within the container control, i raise the event within some event of the control that will generate the message
  • i drag the containerControl into my main window and there manually add the custom event to this with the appropriate method.

This all works just fine - however it does require me to drag all the containers into my window in the IDE and wire this all up beforehand.

The result is the main window becomes quite cluttered in the IDE, with overlapping containers (‘navigation’ is done with containerControl.hide and containerControl.show). And it requires all containers to be initialised when the window loads, which isn’t ideal.

I know i can create a new instance of each container in code and embed it in the window. I know i should be able to use AddHandler, but so far all my attempts to do this for a newly created instance of a containerControl have failed because i don’t quite get how i’m supposed to use AddHandler (in spite Googling this…). I’m hoping one of you XOJO gurus can give a detailed outline on how to do this?

there are at least a couple approaches
add handler is one
interfaces would be another

the question I have BEFORE I would make any specific suggestions is what is “when a message needs to go from the container to the app for some other action” ?
What sorts of messages would this be - as this might suggest an entirely different approach

Hi @npalardy - a typical example would be clicking on elements in a listbox or other buttons that would then initialise another container with the required data referenced from the current container, hide (or close) the current container and show the desired container with the desired data.

As a specific example, at present i have a simple custom event that fires when the user clicks on certain icons in a listbox row in a container. The event sends two strings in the event (the destination container info and an identifier to query the database for data to populate the target container).
Within the subclassed container, the event triggers a method to do the necessary…

Works perfect as is in the built app - but must be more efficient to instantiate and destroy the containers on the fly. Grateful for any pointers!

OK
So its plausible that each container is an “editor” of some kind and when given some information it then “edits” that data (or shows it etc) ?

One of the issues with AddHandler is that you have to know the event name before hand
Its not like you can just randomly use it to add any old handler at any old time
And you have to already have some code set up that matches the required signature for that addhandler

In that regard you might as well define an interface - a consistent API that all these containers would implement - and that the pagepanel etc that they are in could manipulate and rely on

For instance you might consider that each of these containers is an “Editor”
It might have a “Edit” method that is passed some information (like the identifier to query the database for data to populate the target container)
That container then can initialize and load whatever data it needs

Some of this is tricky to try & explain in a textual post

I might need to whip up a little sample and post a link to it for this to make more sense

I’m possibly/probably not following the best paradigm, but got really tired of having to negotiate hundreds of controls and methods in the same window. The IDE is slow at best of time and it would just crawl…

So at present the main window has a top strip that is ‘global’ to all views and the remainder of the window is substituted with a containerControl. This in effects simulates a page panel, but with all the controls/methods/properties parcelled away in their container, making it much simpler to manage.

I’m using custom events to navigate rather than edit. Each container can display and edit/update data on it’s own.

The general structure structure is:
container1 -> click on a section of data to drill down -> send [destination container] + [primary key] to enclosing window

The custom event fires in container1 subclass in enclosing window -> 1) takes text strings, does SQL query and updates a rowSet stored in a global module + 2) hides container1 and shows container2 by triggering a method in container2 to update it’s fields from the rowSet in the module.

Container2 can edit/update/delete records as needed.

If an interface can replace this i’d be keen to try it out. Possibly i guess i could add some properties to store the generated string data to access in an interface?

No doubt

undoutedly

edit/display whatever
events arent only for one purpose :slight_smile:
use them however you see fit

Ah … ok I get this
A message saying what pane to wwitch to

makes sense

makes sense

interfaces might make some things easier

heres a quick sample i banged out that uses two interfaces

EDIT : FWIW I think i have your use case modelled ok but if not please say so
Dont want to give you a bum steer right off the bat :stuck_out_tongue:

1 Like

That’s amazing @npalardy, thank you!
That looks like it will do the trick - and a great way to learn interfaces which as you probably guessed i know little about :slight_smile:

interfaces are a handy way to make lots of different things say “hey I BEHAVE like this”
basically an interface defines a set of methods that can be assured to be present

in this case I ended up using two because the containers need to have a consistent API (ok its just one method but …) so that the “edit” method could be simply & consistently called regardless of whether each one actually does EDIT anything (we could have called that method Init or setup or whatever else might make more sense)

And each of those containers needed to know what thing to tell “ok heres the data you need to know how to move to the other panes and which pane you should move to”

if you have questions ask away

1 Like

FWIW the other comment on that thread about

Typically, you use an Interface to communicate from the outside world (the window, for example) to the container, and events to communicate from the container to the outside world.

Is definitely a COMMON way to do this

The pattern I provided uses 2 interfaces - one for the window/container to communicate to the panels and one for the panels to communicate to the window (or whatever else implements the interface)

Events are wildly useful and in some ways “misunderstood”
They are not JUST for controls
They are a nice simple way to implement certain design patterns like chain of responsibility
And they can be used in other ways
see https://www.great-white-software.com/blog/2020/02/08/using-events-as-a-way-to-pass-information-to-instances/
https://www.great-white-software.com/blog/2019/10/23/about-events/
https://www.great-white-software.com/blog/2019/07/01/how-do-you-raiseevent/
https://www.great-white-software.com/blog/2020/01/21/creating-custom-controls/