By user186249


2009-10-08 09:49:03 8 Comments

I have a ToolStripMenuItem called "myMenu". How can I access this like so:

/* Normally, I would do: */
this.myMenu... etc.

/* But how do I access it like this: */
String name = myMenu;
this.name...

This is because I am dynamically generating ToolStripMenuItems from an XML file and need to reference menuitems by their dynamically generated names.

13 comments

@daniele3004 2017-11-29 08:06:55

One of the best way is a single row of code like this:

In this example we search all PictureBox by name in a form

PictureBox[] picSample = 
                    (PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true);

Most important is the second paramenter of find.

if you are certain that the control name exists you can directly use it:

  PictureBox picSample = 
                        (PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true)[0];

@V1NNY 2016-10-23 17:47:43

Using the same approach of Philip Wallace, we can do like this:

    public Control GetControlByName(Control ParentCntl, string NameToSearch)
    {
        if (ParentCntl.Name == NameToSearch)
            return ParentCntl;

        foreach (Control ChildCntl in ParentCntl.Controls)
        {
            Control ResultCntl = GetControlByName(ChildCntl, NameToSearch);
            if (ResultCntl != null)
                return ResultCntl;
        }
        return null;
    }

Example:

    public void doSomething() 
    {
            TextBox myTextBox = (TextBox) this.GetControlByName(this, "mytextboxname");
            myTextBox.Text = "Hello!";
    }

I hope it help! :)

@carefulnow1 2016-06-26 04:36:42

A simple solution would be to iterate through the Controls list in a foreach loop. Something like this:

foreach (Control child in Controls)
{
    // Code that executes for each control.
}

So now you have your iterator, child, which is of type Control. Now do what you will with that, personally I found this in a project I did a while ago in which it added an event for this control, like this:

child.MouseDown += new MouseEventHandler(dragDown);

@Adriaan Stander 2009-10-08 09:53:17

Use the Control.ControlCollection.Find method.

Try this:

this.Controls.Find()

@RvdK 2009-10-08 09:55:32

@user186249 2009-10-08 10:09:54

This worked perfectly thanks

@Luca 2010-11-28 17:27:04

This doesn't work for me. I think because, as o3o has pointed out, a ToolStripMenuItem is not a Control.

@Dan W 2012-04-16 01:05:46

For a textbox, I had to cast to the control type and take the first element like this: ((TextBox) frm.Controls.Find("controlName",true)[0]).Text = "yay";

@Shaun Luttin 2013-09-28 00:46:16

It doesn't work in the Compact Framework.

@mrid 2017-12-18 09:04:05

@DanW this is so much like Java

@shooky56 2011-09-13 17:40:26

Assuming you have Windows.Form Form1 as the parent form which owns the menu you've created. One of the form's attributes is named .Menu. If the menu was created programmatically, it should be the same, and it would be recognized as a menu and placed in the Menu attribute of the Form.

In this case, I had a main menu called File. A sub menu, called a MenuItem under File contained the tag Open and was named menu_File_Open. The following worked. Assuming you

// So you don't have to fully reference the objects.
using System.Windows.Forms;

// More stuff before the real code line, but irrelevant to this discussion.

MenuItem my_menuItem = (MenuItem)Form1.Menu.MenuItems["menu_File_Open"];

// Now you can do what you like with my_menuItem;

@Koekiebox 2009-10-08 10:06:37

You can do the following:

private ToolStripMenuItem getToolStripMenuItemByName(string nameParam)
   {
      foreach (Control ctn in this.Controls)
         {
            if (ctn is ToolStripMenuItem)
               {
                   if (ctn.Name = nameParam)
                      {
                         return ctn;
                      }
                }
         }
         return null;
    }

@o3o 2010-07-13 11:56:45

this.Controls.Find(name, searchAllChildren) doesn't find ToolStripItem because ToolStripItem is not a Control

  using SWF = System.Windows.Forms;
  using NUF = NUnit.Framework;
  namespace workshop.findControlTest {
     [NUF.TestFixture]
     public class FormTest {
        [NUF.Test]public void Find_menu() {
           // == prepare ==
           var fileTool = new SWF.ToolStripMenuItem();
           fileTool.Name = "fileTool";
           fileTool.Text = "File";

           var menuStrip = new SWF.MenuStrip();
           menuStrip.Items.Add(fileTool);

           var form = new SWF.Form();
           form.Controls.Add(menuStrip);

           // == execute ==
           var ctrl = form.Controls.Find("fileTool", true);

           // == not found! ==
           NUF.Assert.That(ctrl.Length, NUF.Is.EqualTo(0)); 
        }
     }
  }

@dmihailescu 2011-05-11 16:50:59

Assuming you have the menuStrip object and the menu is only one level deep, use:

ToolStripMenuItem item = menuStrip.Items
    .OfType<ToolStripMenuItem>()
    .SelectMany(it => it.DropDownItems.OfType<ToolStripMenuItem>())
    .SingleOrDefault(n => n.Name == "MyMenu");

For deeper menu levels add more SelectMany operators in the statement.

if you want to search all menu items in the strip then use

ToolStripMenuItem item = menuStrip.Items
    .Find("MyMenu",true)
    .OfType<ToolStripMenuItem>()
    .Single();

However, make sure each menu has a different name to avoid exception thrown by key duplicates.

To avoid exceptions you could use FirstOrDefault instead of SingleOrDefault / Single, or just return a sequence if you might have Name duplicates.

@vaNIts 2009-10-28 18:18:38

string name = "the_name_you_know";

Control ctn = this.Controls[name];

ctn.Text = "Example...";

@dmihailescu 2011-05-13 13:57:06

the only issue with ToolStripMenuItem is that it is not a Control and your code won't work. ;(

@TechNyquist 2014-07-11 08:54:12

Actually this answer is closer to the question to me.

@Philip Wallace 2009-10-28 18:33:45

this.Controls["name"];

This is the actual code that is ran:

public virtual Control this[string key]
{
    get
    {
        if (!string.IsNullOrEmpty(key))
        {
            int index = this.IndexOfKey(key);
            if (this.IsValidIndex(index))
            {
                return this[index];
            }
        }
        return null;
    }
}

vs:

public Control[] Find(string key, bool searchAllChildren)
{
    if (string.IsNullOrEmpty(key))
    {
        throw new ArgumentNullException("key", SR.GetString("FindKeyMayNotBeEmptyOrNull"));
    }
    ArrayList list = this.FindInternal(key, searchAllChildren, this, new ArrayList());
    Control[] array = new Control[list.Count];
    list.CopyTo(array, 0);
    return array;
}

private ArrayList FindInternal(string key, bool searchAllChildren, Control.ControlCollection controlsToLookIn, ArrayList foundControls)
{
    if ((controlsToLookIn == null) || (foundControls == null))
    {
        return null;
    }
    try
    {
        for (int i = 0; i < controlsToLookIn.Count; i++)
        {
            if ((controlsToLookIn[i] != null) && WindowsFormsUtils.SafeCompareStrings(controlsToLookIn[i].Name, key, true))
            {
                foundControls.Add(controlsToLookIn[i]);
            }
        }
        if (!searchAllChildren)
        {
            return foundControls;
        }
        for (int j = 0; j < controlsToLookIn.Count; j++)
        {
            if (((controlsToLookIn[j] != null) && (controlsToLookIn[j].Controls != null)) && (controlsToLookIn[j].Controls.Count > 0))
            {
                foundControls = this.FindInternal(key, searchAllChildren, controlsToLookIn[j].Controls, foundControls);
            }
        }
    }
    catch (Exception exception)
    {
        if (ClientUtils.IsSecurityOrCriticalException(exception))
        {
            throw;
        }
    }
    return foundControls;
}

@Neil 2009-10-08 09:56:53

Have a look at the ToolStrip.Items collection. It even has a find method available.

@Julien Lebosquain 2009-10-08 09:53:54

Since you're generating them dynamically, keep a map between a string and the menu item, that will allow fast retrieval.

// in class scope
private readonly Dictionary<string, ToolStripMenuItem> _menuItemsByName = new Dictionary<string, ToolStripMenuItem>();

// in your method creating items
ToolStripMenuItem createdItem = ...
_menuItemsByName.Add("<name here>", createdItem);

// to access it
ToolStripMenuItem menuItem = _menuItemsByName["<name here>"];

@anonymous coward 2009-10-08 09:55:52

Now THERE'S an idea! +1 (although only works if the control is already in the dictionary)

@anonymous coward 2009-10-08 09:53:42

Control GetControlByName(string Name)
{
    foreach(Control c in this.Controls)
        if(c.Name == Name)
            return c;

    return null;
}

Disregard this, I reinvent wheels.

@anonymous coward 2009-10-08 09:57:50

More of a general-purpose-ish solution than Julien's. Still works fine though.

@Vikyboss 2011-09-15 21:18:48

Awesome solution, this is what I was looking for long time. Thanks! :)

@B. Clay Shannon 2014-01-29 19:11:26

General-purpose-ish is good! +1

@barlop 2016-04-20 08:17:42

this is not reinventing the wheel, it's a good solution that can be easily adapted to the case where you don't know a control's name or want to view the names of each control or do many things accessing controls, and was thus useful to me.

Related Questions

Sponsored Content

61 Answered Questions

[SOLVED] What is the difference between String and string in C#?

47 Answered Questions

[SOLVED] How do I update the GUI from another thread?

13 Answered Questions

27 Answered Questions

[SOLVED] How do I enumerate an enum in C#?

9 Answered Questions

[SOLVED] What are the correct version numbers for C#?

19 Answered Questions

[SOLVED] Proper use of the IDisposable interface

296 Answered Questions

[SOLVED] Hidden Features of C#?

  • 2008-08-12 16:32:24
  • Serhat Ozgel
  • 658930 View
  • 1476 Score
  • 296 Answer
  • Tags:   c# hidden-features

24 Answered Questions

[SOLVED] Cast int to enum in C#

  • 2008-08-27 03:58:21
  • lomaxx
  • 1173599 View
  • 2847 Score
  • 24 Answer
  • Tags:   c# enums casting

38 Answered Questions

5 Answered Questions

[SOLVED] Is there a reason for C#'s reuse of the variable in a foreach?

Sponsored Content