所以,在this question之后,我一直试图处理一种方法,当我点击某个项目时停止下拉菜单关闭。
在链接的问题中,有一个这样的答案表明我将AutoClose
属性设置为false。我这样做了,这确实实现了我的要求。但是,我实现它的方式意味着下拉菜单被强制打开。
表单代码:
public void ToolStripMenuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem item = sender as ToolStripMenuItem;
if (item != null)
item.Checked = !item.Checked;
item.DropDown.AutoClose = false;
}
我知道为什么会这样 - 实现意味着无法将AutoClose
设置为true。但是,由于menuItems是在不同的类中动态生成的,因此我没有任何要引用的事件或对象。
此代码从主窗体复制菜单结构,并将其复制以在“配置文件视图”中重新创建它(以设置用户可以/不能看到的内容)。
控制器代码:
private void PopulateProfileView(User_AccessProfilesView view, Menu_View mainMenu)
{
// Disabled Items are not able to be set, becasue they are either always visible for every user,
// or only visible to specific users (Administrator)
List<string> disabledMenuItems = new List<string>();
List<string> disabledSubMenuItems = new List<string>();
bool error = false;
bool subError = false;
_groupDictionary = new Dictionary<string, List<string>>();
// Populate the disallowed Menu Items from the Main Menu,
// and then add the items specific to the Profile View
disabledMenuItems.Add("File");
disabledMenuItems.Add("Administrator");
disabledMenuItems.Add("Help");
disabledMenuItems.Add("Te&rminations");
disabledMenuItems.AddRange(mainMenu.disallowedMenuItems);
// Populate the disallowed Sub Menu Items from the Main Menu,
// and then add the items specific to the Profile View
disabledSubMenuItems.Add("View All");
disabledSubMenuItems.AddRange(mainMenu.disallowedSubItems);
foreach (ToolStripMenuItem item in mainMenu.mainMenuStrip.Items)
{
ToolStripMenuItem menuItem = new ToolStripMenuItem(item.Text);
if (error == false)
{
// Add to the menu bar
view.menuStrip.Items.Add(menuItem);
menuItem.Click += new EventHandler(view.ToolStripMenuItem_Click);
foreach (ToolStripItem dropItem in item.DropDownItems)
{
if (dropItem is ToolStripMenuItem)
{
ToolStripMenuItem menuDropItem = new ToolStripMenuItem(dropItem.Text);
// Same concerns as above with regards to doing a substring check
// to decide if menu items should be excluded or not.
foreach (string s1 in disabledSubMenuItems)
{
if (!menuDropItem.Text.Contains(s1))
{
subError = false;
}
else
{
subError = true;
break;
}
}
if (!subError)
{
menuItem.DropDownItems.Add(menuDropItem);
menuDropItem.Click += new EventHandler(view.ToolStripMenuItem_Click);
}
}
else if (dropItem is ToolStripSeparator)
{ menuItem.DropDownItems.Add(new ToolStripSeparator()); }
}
如何正确实现AutoClose
属性,以便在单击菜单项时,菜单不会关闭,但如果单击菜单标题,或将鼠标从菜单中移开,或者选择另一个菜单(通过单击或鼠标悬停),菜单会关闭吗?
道歉,如果这是一个简单的问题 - 我已经离开游戏大约一年了,不得不重新回到这一点,并且在一切正常后我会遇到一些问题。
答案 0 :(得分:2)
要解决此问题,您可以按照以下步骤操作:
您应确定哪些菜单项在点击后仍应保持打开状态。我将使用“keepopen”作为Tag
属性的值,用于那些在点击后应保持打开的项目。
对于包含这些项目的菜单项,您需要获取DropDown
属性并处理其ItemClicked
事件,并且在ItemClicked
事件中,您应该检查单击的项是其中一个"keepopen"
项,然后将容器菜单项的DropDown.AutoClose
设置为false
。对于其他项目,请将其设置为true
。它会阻止在点击时关闭这些"keepopen"
项目,同时通过点击关闭其他项目。
您应该处理这些CheckedChanged
项的"keepopen"
个事件,并将DropDown.AutoClose
设置为true
。在使用Click
事件处理程序时,我们阻止了项目关闭,这里我们再次启用关闭,因此如果用户单击菜单外部,它将关闭。
然后这就是结果,看鼠标点击:
示例强>
例如,创建一个空表单并处理其Load
事件并使用以下代码。当您点击SubMenu1
,SubMenu2
或SubMenu3
时,只需选中或取消选中它们,而无需关闭菜单。但是你点击菜单外面或SubMenu4
,它会关闭菜单。
const string keepopen = "keepopen";
private void Form1_Load(object sender, EventArgs e)
{
var menuStrip = new MenuStrip() { Dock = DockStyle.Top };
this.Controls.Add(menuStrip);
var menu1 = (ToolStripMenuItem)menuStrip.Items.Add("Menu1");
menu1.DropDownItems.Add(new ToolStripMenuItem("Submenu1")
{ Tag = keepopen, CheckOnClick = true });
menu1.DropDownItems.Add(new ToolStripMenuItem("Submenu2")
{ Tag = keepopen, CheckOnClick = true });
menu1.DropDownItems.Add(new ToolStripMenuItem("Submenu3")
{ Tag = keepopen, CheckOnClick = true });
menu1.DropDownItems.Add("-");
menu1.DropDownItems.Add(new ToolStripMenuItem("Submenu4"));
menu1.DropDown.ItemClicked += (obj, args) =>
{
if (args.ClickedItem.Tag == keepopen)
menu1.DropDown.AutoClose = false;
else
menu1.DropDown.AutoClose = true;
};
menu1.DropDownItems.OfType<ToolStripMenuItem>()
.Where(x => x.Tag == keepopen)
.ToList().ForEach(x =>
{
x.CheckedChanged += (obj, args) =>
{
menu1.DropDown.AutoClose = true;
};
});
}