在C#中动态过滤菜单(ContextMenuStrip)而不重新创建菜单?

时间:2011-12-14 22:10:00

标签: c# .net winforms contextmenu contextmenustrip

这可能吗?

我计划有10个菜单项,这些菜单项将包含子菜单项(仅限1级)。我希望能够在用户输入TextBox控件时过滤它们。我知道我可以在第一次打开菜单时过滤项目,但是我希望能够在用户输入类别菜单项没有适用于当前过滤器的子项时动态地过滤它来进行过滤(通过名称过滤)。

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

我添加了一个上下文菜单条(menuStrip1)。为此我添加了以下内容:

File
   Exit

Edit
   Copy
   Paste
       Further Down

Help
   Arghhhh!

然后我添加了一个文本框(FilterMenuText),并在OnTextChanged事件中执行以下操作:

    private void FilterMenuText_TextChanged(object sender, EventArgs e)
    {

        foreach (ToolStripMenuItem menuItem in menuStrip1.Items)
        {
            if (menuItem.DropDownItems.Count > 0)
            {
                bool matchFound = false;

                foreach (ToolStripMenuItem childMenuItem in menuItem.DropDownItems)
                {
                    if (childMenuItem.Text.ToUpper().Contains(FilterMenuText.Text.ToUpper()))
                    {
                        matchFound = true;
                        break;
                    }
                }

                menuItem.Visible = matchFound;

            }
        }

    }

这将根据子菜单项的内容隐藏和显示顶级MenuItem。如果您的菜单有多个级别的下拉菜单,请将foreach放入递归函数,例如:

private void FilterMenuText_TextChanged(object sender, EventArgs e)
{

    foreach (ToolStripMenuItem menuItem in menuStrip1.Items)
    {
        menuItem.Visible = MenuItemHasChildWithName(menuItem, FilterMenuText.Text);
    }

}


private bool MenuItemHasChildWithName(ToolStripMenuItem menuItem, string name)
{

    if (!menuItem.HasDropDownItems)
    {
        return false;
    }

    bool matchFound = false;

    foreach (ToolStripMenuItem childMenuItem in menuItem.DropDownItems)
    {

        if (childMenuItem.Text.ToUpper().Contains(name.ToUpper()))
        {
            matchFound = true;
            break;
        }

        if (childMenuItem.HasDropDownItems)
        {
            matchFound = MenuItemHasChildWithName(childMenuItem, name);

            if(matchFound) { break; }

        }

    }

    return matchFound;

}

答案 1 :(得分:2)

这是我在上下文菜单中有条件地显示菜单项时使用的。如果您使用相同的菜单而不想显示它,则只需将同一循环中的每个项目设置为true;

    private void dgViewData_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            if (dgViewData.HitTest(e.X, e.Y).Type != DataGridViewHitTestType.ColumnHeader)
            {
                foreach (ToolStripMenuItem menuItem in conMicImport.Items)
                {
                    menuItem.Visible = menuItem.Text.ToString().Contains("Add") == true ? false : true;
                }

                conMicImport.Show(dgViewData, e.Location);
                ctxtDG = dgViewData;
            }
        }

    }

答案 2 :(得分:1)

当您不希望它出现时,将toolstrip对象的Visible属性设置为false。

答案 3 :(得分:1)

出于示例目的,我使用Web表单应用程序

完成了此操作
foreach (Control c in Page.Form.Controls)
            {
                //Response.Write("WORD2" + c.GetType());
                if (c is Panel)
                {
                    foreach (Control p in c.Controls)
                    {
                        if (p is CheckBoxList)
                        {
                            foreach (ListItem li in ((CheckBoxList)p).Items)
                            {
                                li.Selected = false;
                            }
                        }
                    }
                }
            }