【问题标题】:MenuItem AutoClose = false on dynamically generated Toolstrip MenuMenuItem AutoClose = false 在动态生成的工具条菜单上
【发布时间】:2017-11-01 11:13:30
【问题描述】:

因此,在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 属性,这样如果我点击菜单项,菜单不会关闭,但如果我点击菜单标题,或者将鼠标从菜单上移开,或者选择另一个菜单(通过单击或鼠标悬停),菜单是否关闭?


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

【问题讨论】:

  • 单击时不会关闭的菜单是工具栏。你的工具箱里有一个。

标签: c# .net winforms toolstripdropdown


【解决方案1】:

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

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

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

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

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

示例

例如,创建一个空表单并处理其Load 事件并使用以下代码。当您单击SubMenu1SubMenu2SubMenu3 时,它们将被选中或取消选中,而无需关闭菜单。但是你点击菜单外或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;
            };
        });
}

【讨论】:

  • 如果您在应用解决方案时遇到任何问题,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多