Question

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?

Was it helpful?

Solution

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;

}

OTHER TIPS

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

    }

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

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;
                            }
                        }
                    }
                }
            }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top