Dynamic menu handling

A lot of times when you need to create a menu at runtime you don’t know the number of items and those items may require some additional data to be handled correctly like a folder item, window reference etc. And in cases like this a subclass of MenuItem makes sense so you can add properties to the subclass and implement the action event to handle that extra data. This is a common pattern for things like the Window menu, Font menu and Recent items.

But its not the only way to handle a dynamic menu.

Suppose you want to add a menu at runtime that is well known before hand and depending on which user is using your application the menu has different entries ?

In such a case you can define everything ahead of time and it will all behave just like if you had defined it in the IDE menu editor.

The trick is to know that the “AutoEnable” setting for menus is dependent on the NAME of the menu item, not the text it contains.

Lets see how we can take advantage of this fact.

Create a new desktop application. In Window1’s open event we’re going to add a menu, and some items to that menu.

Add the following code to the Open event


Dim SelfMenu As New MenuItem("Self Service")
Self.MenuBar.Append SelfMenu
SelfMenu.Enabled = True

Dim fMenu As MenuItem

fMenu = New MenuItem("selfchgpswd")
fMenu.Name = "selfchgpswd"
fMenu.Text = "Change Password"
fMenu.AutoEnable = True
SelfMenu.Append(fMenu)

Note that we have set the name. THIS is crucial. And each item added should have a unique name otherwise you can end up with odd problems.

If you run at this point you should see the menu is added but the items are not enabled. But note that we DID set the AutoEnable property. The Xojo runtime will automatically enable this item IF there is a handler for it on our Window.

So lets add a menu handler for selfchgpswd (menu handlers use the NAME to match the menu item with the menu handler to be enabled & executed)

Right click on Window1 in the navigator and select “Add to Window1” and add a menu handler. In the editor field for the menu handler name put in selfchgpswd. You CAN define a menu handler for menu items that do not exist.

In the menu handler simply add

break

And now run.

First you will see that the menu is added AND the item is now enabled ! And if you select that item from the menu you should stop at the break statement – the Code in the menu handler IS being called exactly as we expected.

At the end of the day this gives you a second way to handle menu items that you add and remove at runtime and, in this case, you know beforehand and can add the code just like you would have if you had defined the menu in the Menu editor.

Enjoy !