No WebToolBar MenuSelected WebToolbarButton Event?

When using the WebToolBar I often need to ‘refresh’ the captions and icons of items, based on conditions (outside of the WebToolbarButton). Which all works great, except…

When the WebTimer responsible for keeping the menu items updated fires, any updates to menu items caused focus to drop. The issue with this is that a drop-down selection immediately rolls up, stealing away the drop-down from the end user.

I’ve tried creating a Boolean that bypasses refreshing, but I’d prefer to disable the refresh timer while the end user is interacting with the WebToolBar.

There aren’t any events (that I see) that trigger when a user presses the WebToolbarButton, so no way to know they’re looking at the drop-down, thus it gets wiped away by the refresh timer.

Any of-the-shelf solutions for ‘detecting’ when the user is interacting with the WebToolbar? Thx

Why are you using a timer for changing things instead of when the things actually change.

Great question, I have some menus that say “Pause XYZ” and it becomes “Resume XYZ” once pressed - but that change has to reflect across all instances and sessions so everyone’s menu updates accordingly. The timer is merely relaying a change in a centralized database, and reflecting it in the menu item(s).

I have a suggestion. Instead of using a timer, how about using a messager to only send updates when necessary? Then the only time this would be an issue is if the state changes

1 Like

Would your suggestion work across multiple instances of a WebApp?

Yup. A timer (not a WebTimer) is used to send the messages. I can put an example together for you later today.

1 Like

Ok, here’s an example…

messaging example.xojo_binary_project.zip (10.6 KB)

I tried to cover the basic scenarios:

  1. A global property (on app at the moment) that indicates the Paused/Resumed state so a new window can be initialized into the proper state.
  2. A Messaging Module (Messaging) containing a class interface (Receiver) and a message for registering receivers and sending messages.

If you run the example project and open multiple sessions you’ll see that the label and button caption are kept in sync across all active sessions. It still uses a timer, but the message is only sent when the state actually changes.

Basically, for an item to receive messages, you need to apply the Messaging.Receiver class interface to the object. This will add a method to the item called MessageReceived. In the object’s Constructor or Opening event you’ll need to call Me.RegisterForMessages(). That’s it!

For sending messages to the receivers, you simply need to call the Messaging.Send method. Now I’ve used an enum for the message type and the reason for this is to avoid typing errors. After many years of using this type of setup with a String for the type and then either forgetting or mistyping the message type, I just started using enums. So any time you want to send a message you’d type something like this:

Messaging.Send(Messaging.MessageTypes.Resume)

Things to keep in mind:

The Send method also takes a second parameter Data as Variant which defaults to Nil. If you need to send data along, that would go there. Make sure the data isn’t session specific because it won’t be accessible if sent to a different session.

When Sending, it’s important watch out for recursive loops. It’s entirely possible that you could send a message (A) that triggers message B, which would in turn trigger message A. Your app will lock up in a big hurry and you may never receive a StackOverflowException.

Please excuse my use of the Dim keyword. I’m a Xojo old-timer.

2 Likes

First, thank you for the major investment in this post! Secondly, I look forward to seeing what you sent and giving it a thorough exam.

I feel like I bear some responsibility in how web 2 turned out and having done most of the maintenance work on web 1, I have a pretty good idea about how the framework works under the hood. If I can offer solutions that help people get over their hurdles and I have the time available, I’m happy to do it.

4 Likes