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

发布于 2024-12-21 09:49:01 字数 186 浏览 2 评论 0原文

这可能吗?

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

有什么想法吗?

Is this possible?

I plan to have 10 menu items where these are going to have sub-menu items (1 level deep only). I want to be able to filter them when the user types into my TextBox control. I know I can filter items upon opening the menu for the first time, but I want to be able to continually filter it as the user types and hide categories on the fly when the category menu item has no subitems applicable for the current filter (by name filtering).

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

假装不在乎 2024-12-28 09:49:01

我添加了一个上下文菜单条(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;

            }
        }

    }

这将根据子菜单项的内容适当隐藏和显示顶级菜单项。如果您的菜单有不止一级的下拉菜单,请将 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;

}

I added a context menu strip (menuStrip1). To this I added the following:

File
   Exit

Edit
   Copy
   Paste
       Further Down

Help
   Arghhhh!

I then added a text box (FilterMenuText), and, on the OnTextChanged event, do the following:

    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;

            }
        }

    }

This will hide and show the top level MenuItems as appropriate based on the content of the child menu items. If your menu has more than one level of drop down, put the foreach into a recursive function, like:

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;

}
顾北清歌寒 2024-12-28 09:49:01

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

    }

This is what I used for conditionaly showing menu items on a context menu. If you use the same menu and don't want to show it, you merely set each item in the same loop to 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;
            }
        }

    }
雨轻弹 2024-12-28 09:49:01

当您不希望工具条对象出现时,将其 Visible 属性设置为 false。

Set the toolstrip object's Visible property to false when you don't want it to appear.

止于盛夏 2024-12-28 09:49:01

出于示例目的,我使用网络表单应用程序完成了此操作

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;
                            }
                        }
                    }
                }
            }

for example purposes I have done this using a web forms application

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;
                            }
                        }
                    }
                }
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文