1

所以,在这个问题之后,我一直在尝试处理一种方法来阻止当我单击一个项目时关闭下拉菜单。

在链接的问题中,一个这样的答案建议我将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正确实现该属性,以便如果单击菜单项,菜单不会关闭,但如果单击菜单标题,或将鼠标移离菜单,或选择另一个菜单(通过单击或鼠标悬停),菜单是否关闭?


如果这是一个简单的问题,我深表歉意——我已经退出游戏大约一年了,不得不重新开始,我在正确处理所有事情时遇到了一些问题。

4

1 回答 1

2

要解决此问题,您可以按照以下步骤操作:

  1. 您应该确定哪些菜单项即使在单击后仍应保持打开状态。Tag对于那些在单击后应保持打开的项目,我将使用“keepopen”作为属性值。

  2. 对于包含这些项目的菜单项,您需要获取DropDown属性并处理其ItemClicked事件,在ItemClicked事件中,您应该检查单击的项目是否是这些"keepopen"项目之一,然后将DropDown.AutoClose容器菜单项设置为false. 对于其他项目,将其设置为true。它将阻止"keepopen"单击时关闭这些项目,而让其他项目通过单击关闭。

  3. 您应该处理CheckedChanged这些"keepopen"项目的事件并设置DropDown.AutoClosetrue. 在使用Click事件处理程序时,我们阻止了项目关闭,在这里我们再次启用关闭,因此如果用户单击菜单外部,它将关闭。

那么这将是结果,看看鼠标点击:

在此处输入图像描述

例子

例如,创建一个空表单并处理其Load事件并使用以下代码。当您单击或时SubMenu1,它们将被选中或取消选中而不关闭菜单。但是您在菜单外单击或单击,它将关闭菜单。SubMenu2SubMenu3SubMenu4

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;
            };
        });
}
于 2017-10-31T13:28:15.750 回答