How to disable ToolStripMenuItem in Context menu Dynamically?

Nighil picture Nighil · Jan 14, 2011 · Viewed 12.4k times · Source

In my windows application i have a context menu with a grid the problem is that I want to disable the ToolStripMenuItem in context menu according to the user previlages.How can i do that. i have done like this but it is not working

private void contextMenuStrip_Machine_Opening(object sender, CancelEventArgs e)
{
    toolStripAuthorize.Enabled = INFOpermission.accessAuthorize;
} 

but it is not working

Answer

Cody Gray picture Cody Gray · Jan 14, 2011

You need to set toolStripAuthorize.Enabled to either true or false.

I have no idea what INFOpermission.accessAuthorize is because you didn't show the code that defines that (enum?), but if it's anything other than false, this isn't going to work out like you expect.

I can guarantee that setting the Enabled property of the ToolStripMenuItem that you want to disable to false in the Opening event handler will work. If it's not working for you, you're doing something else wrong, and you need to give us some more information to go on.

If you're stuck, see the sample code here: How to: Handle the ContextMenuStrip Opening Event


EDIT: Armed with new information provided in the comments, I've now isolated the source of the problem. You've assigned the ContextMenuStrip to the RowTemplate of a DataGridView control, and are therefore not able to modify items contained in that context menu in its Opening event handler method.

It turns out that this is a known bug that someone decided was "by design". You can see the original bug report here on Microsoft Connect. The explanation given is that whenever a new row is created based on the RowTemplate (which is how the RowTemplate works), the ContextMenuStrip that you've assigned gets cloned as well. That means the same context menu instance is not used for each row, and whatever properties that you try to set on the original menu items have no effect.

Fortunately, it also gives us a workaround. Like all events, the Opening event passes the actual instance of the ContextMenuStrip that is about to be opened as its sender parameter. This is the context menu whose items you need to modify in order for your alterations to be visible.

So what's the code? It looks like this:

private void contextMenuStrip_Opening(object sender, CancelEventArgs e)
{
    ContextMenuStrip cmnu = (ContextMenuStrip)sender;
    cmnu.Items[1].Enabled = false;
}

Notice, though, that you'll have to reference the individual menu item that you want to modify by its index. This is just the zero-based position of the item in the menu that you want to modify. You can't use the toolStripAuthorize object like you were trying to do before because a new instance of it has been cloned for each new context menu instance.