Context: Mac Mojave : Xojo 2019 3.1
I have one menu bar. I am using the default one and have not changed its name so it is called MainMenuBar.
Let’s say that I have a menu on that menu bar called DesignMenu with several MenuItems. For this example, I will have three MenuItems called miOne and miTwo and miThree.
miOne is not AutoEnabled. miTwo and miThree are AutoEnabled. Assume all three have a MenuHandlers that have some code in them.
As I understand the situation, there is only one place that you can run code and expect it to have any effect on the Enabled/Disabled status of MenuItems. That is in the EnableMenuItems Event Hander of the App. You can write code like miOne.Enabled = True
in the action event of a button or the open event of a window, for example, and it will have absolutely no effect.
So we are focused on the code in the EnableMenuItems Event Hander of the App.
If I write here, miOne.Enabled = True
, then when I click on that DesignMenu it will not be grayed out. If I do not write that code there, it will be grayed out because miOne was not Auto Enabled.
If I write here, miTwo.Enabled = False
, then when I click on that DesignMenu it will be grayed out even though it was Auto Enabled.
If I want all the MenuItems to be grayed out, I can write in the Event Handler
miTwo.Enabled = False
miThree.Enabled = False
miOne will be grayed out because it was not AutoEnabled. miTwo and miThree will be grayed out because you explicitly asked that they not be Enabled.
Here is my first question. Is there any way that you can gray out the display of the Menu itself? At this particular time, all its MenuItems are grayed out. The user will find this out when he clicks on the Menu. But is there a way you can telegraph this to the user before he clicks on the Menu by graying out the display of that particular Menu in the MainMenuBar?
My impression is that this is impossible. Certainly, I cannot figure out how to do this. It there is a way, I would like to know it.
And yet there is a command, DesignMenu.Enabled = False
, that is accepted. Just what does it do? First of all, it does not do anything if it is not run in the EnableMenuItems Event Hander of the App. We have finally become used to that. But what happens if the code is run there? I write in the Event Hander
miOne.Enabled = True
DesignMenu.Enabled = False
What happens when I run that experiment is that when I click on the DesignMenu the first time, all the items show up in black. If I let up on the mouse and click again, they are all grayed out. I find that kind of peculiar. I don’t understand why when I click on it the first time, Xojo does not just “figure out” that my intent is that have them all grayed out since I included DesignMenu.Enabled = False
. Somehow that is functionally not equivalent to writing instead
miTwo.Enabled = False
miThree.Enabled = False
If I do that those two items are grayed out the first time that I click on the menu.
Now Xojo seems to aware of this issue because the language includes a Method called EnableMenuItems. That is confusing because there is an Event Handler of the App that goes by this same name. An improvement with 2019r2 is that calling this Method with this name is deprecated. Now you are supposed to use App.RefreshMenuBar. It does the same thing as best I can tell, but it does not have the confusing name.
I stand to be corrected, but this seems to basically run the EnableMenuItems Event Handler of the App. It is equivalent to that first click that we had the user do above. Now when the user clicks on the Menu for the first time, everything is grayed out rather than having to wait for the second clicking on the Menu.
So as I understand the situation, if you have a Menu and you want all the items to be grayed out you have a choice. In the EnableMenuItems Event Hander of the App include the code for each MenuItem
miTwo.Enabled = False
miThree.Enabled = False
miFour.Enabled = False
miFive.Enabled = False
etc.
In some ways, the above seems simplest all though it involves multiple lines of code. The first time the user clicks on the Menu, all the MenuItems will be grayed out. An alternative is to simply write the one line of code in the EnableMenuItems Event Hander of the App
DesignMenu.Enabled = False
but if you do this without previously calling the method App.RefreshMenuBar, you will get the peculiar phenomena of the user clicking the first time and seeing all the MenuItems in black and then clicking again and seeing them all grayed out.
What I am writing above seems sort of peculiar so I am asking for a confirmation that it is correct.
- Is this is correct usage of
DesignMenu.Enabled = False
? Is that its purpose for existing? - Does App.RefreshMenuBar exist simply to deal with the problem of the first click looking different than the second click if you do use
DesignMenu.Enabled = False
? - If I am content to explicitly, one by one, go through every MenuItem like
miTwo.Enabled = False
then is it true that I have no reason to ever useDesignMenu.Enabled = False
and I will never have any use for the method App.RefreshMenuBar? For me, if there is no other reason for these two things, I would just as soon empty my brain of their very existence.