如何动态地禁用上下文菜单中的ToolStripMenuItem?

Nig*_*hil 2 .net c# toolstrip contextmenustrip winforms

在我的Windows应用程序中,我有一个带网格的上下文菜单,问题是我想根据用户previlages在上下文菜单中禁用ToolStripMenuItem.我怎么能这样做.我这样做了但是没有用

private void contextMenuStrip_Machine_Opening(object sender, CancelEventArgs e)
{
    toolStripAuthorize.Enabled = INFOpermission.accessAuthorize;
} 
Run Code Online (Sandbox Code Playgroud)

但它不起作用

Cod*_*ray 6

您需要设置toolStripAuthorize.Enabledtruefalse.

我不知道是什么INFOpermission.accessAuthorize,因为你没有显示定义它的代码(枚举?),但如果它不是false,那么这就不会像你期望的那样成功.

我可以保证的是,设置Enabled属性ToolStripMenuItem要禁用falseOpening事件处理程序将工作.如果它不适合你,那你就做错了其他事情,你需要给我们一些更多的信息.

如果您遇到困难,请在此处查看示例代码:如何:处理ContextMenuStrip打开事件


编辑:有了评论中提供的新信息,我现在已经隔离了问题的根源.你分配ContextMenuStripRowTemplate一个的DataGridView控制,因此是不能修改包含在其这方面的菜单项Opening事件处理方法.

事实证明,这是一个已知的错误,有人认为是"按设计".您可以在Microsoft Connect上看到原始错误报告.给出的解释是,每当根据RowTemplate(RowTemplate工作方式)创建新行时ContextMenuStrip,您分配的内容也会被克隆.这意味着每行不使用相同的上下文菜单实例,并且您尝试在原始菜单项上设置的任何属性都不起作用.

幸运的是,它也为我们提供了一种解决方法.与所有事件一样,Opening事件将传递ContextMenuStrip即将打开的实际实例作为其sender参数.是上下文菜单,您需要修改其中的项目才能看到您的更改.

那么代码是什么?它看起来像这样:

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

但请注意,您必须引用要通过其索引修改的单个菜单项.这只是您要修改的菜单中项目的从零开始的位置.您不能toolStripAuthorize像以前那样使用该对象,因为已为每个新的上下文菜单实例克隆了它的新实例.