Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中动态筛选菜单(ContextMenuStrip),而不重新创建菜单?_C#_.net_Winforms_Contextmenu_Contextmenustrip - Fatal编程技术网

在C#中动态筛选菜单(ContextMenuStrip),而不重新创建菜单?

在C#中动态筛选菜单(ContextMenuStrip),而不重新创建菜单?,c#,.net,winforms,contextmenu,contextmenustrip,C#,.net,Winforms,Contextmenu,Contextmenustrip,这可能吗 我计划有10个菜单项,其中将有子菜单项(仅1级深度)。我希望能够在用户输入我的文本框控件时过滤它们。我知道我可以在第一次打开菜单时过滤项目,但我希望能够随着用户类型不断过滤项目,并在类别菜单项没有适用于当前过滤器的子项目时动态隐藏类别(按名称过滤) 有什么想法吗?如果不希望toolstrip对象的Visible属性出现,请将其设置为false。例如,我使用web表单应用程序完成了此操作 foreach (Control c in Page.Form.Controls)

这可能吗

我计划有10个菜单项,其中将有子菜单项(仅1级深度)。我希望能够在用户输入我的
文本框
控件时过滤它们。我知道我可以在第一次打开菜单时过滤项目,但我希望能够随着用户类型不断过滤项目,并在类别菜单项没有适用于当前过滤器的子项目时动态隐藏类别(按名称过滤)


有什么想法吗?

如果不希望toolstrip对象的Visible属性出现,请将其设置为false。

例如,我使用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;
                            }
                        }
                    }
                }
            }

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

File
   Exit

Edit
   Copy
   Paste
       Further Down

Help
   Arghhhh!
    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;

            }
        }

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

File
   Exit

Edit
   Copy
   Paste
       Further Down

Help
   Arghhhh!
    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;

            }
        }

    }
这将根据子菜单项的内容酌情隐藏和显示顶级菜单项。如果您的菜单有多个级别的下拉列表,请将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;

}

这就是我用来在上下文菜单上有条件地显示菜单项的方法。如果您使用相同的菜单并且不想显示它,您只需将同一循环中的每个项目设置为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;
            }
        }

    }

您是否可以在compentlevel中根据文本框或其名称检查其类型?您始终可以禁用不需要的菜单项。在我的应用程序中,我只是动态创建了菜单。是的,我没有设计师的支持,但这是相当容易做到的。唯一让我感到困扰的是,菜单确实比正常的菜单位置弹出了至少10或20个像素。谢谢DJ,我不知道你的评论是什么意思,但我不需要检查类型,只是菜单项。我将做一些实验。我的意思是,如果它是一个文本框,你的文本框控件的类型或名称将被替换为我的带有标签等的示例CheckListbox。。。您可以在菜单项上执行相同的检查。我给你这个作为起点。。同样的事情也适用于windows窗体,只需将Page.Form.Controls替换为Form.Controls hanks,这看起来不错。顺便说一句,你为什么用上而不用下?习惯的力量。有人曾经提到ToUpper速度更快(因此它在我曾经参与的一个项目中被广泛使用),但事实并非如此。ToUpper()已优化,但ToUpper()和ToLower()是一个选择问题。在可能的情况下,我使用String.Compare,但在本例中,您希望查看键入的字母是否是名称的一部分,因此使用了Contains。严格地说,对于cluture不变量比较()来说,IndexOf可能是一个更好的选择,但我很懒。