Obtener un control de Windows Forms por nombre en C #

Tengo un ToolStripMenuItem llamado “myMenu”. ¿Cómo puedo acceder a esto así?

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

Esto se debe a que estoy generando ToolStripMenuItems dinámicamente a partir de un archivo XML y necesito hacer referencia a los elementos de menú por sus nombres generados dinámicamente.

Use el método Control.ControlCollection.Find .

Prueba esto:

 this.Controls.Find() 
 string name = "the_name_you_know"; Control ctn = this.Controls[name]; ctn.Text = "Example..."; 
 Control GetControlByName(string Name) { foreach(Control c in this.Controls) if(c.Name == Name) return c; return null; } 

Sin tener en cuenta esto, reinventar ruedas.

Suponiendo que tiene el objeto menuStrip y el menú tiene solo un nivel de profundidad, use:

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

Para niveles de menú más profundos, agregue más operadores SelectMany en la statement.

si desea buscar todos los elementos del menú en la tira, utilice

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

Sin embargo, asegúrese de que cada menú tenga un nombre diferente para evitar la excepción lanzada por duplicados de claves.

Para evitar excepciones, puede utilizar FirstOrDefault lugar de SingleOrDefault / Single , o simplemente devolver una secuencia si tiene Name duplicados.

this.Controls.Find (name, searchAllChildren) no encuentra ToolStripItem porque ToolStripItem no es un 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)); } } } 

Dado que los está generando dinámicamente, mantenga un mapa entre una cadena y el elemento del menú, que permitirá una recuperación rápida.

 // in class scope private readonly Dictionary _menuItemsByName = new Dictionary(); // in your method creating items ToolStripMenuItem createdItem = ... _menuItemsByName.Add("", createdItem); // to access it ToolStripMenuItem menuItem = _menuItemsByName[""]; 
 this.Controls["name"]; 

Este es el código real que se ejecuta:

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

Suponiendo que tiene Windows.Form Form1 como el formulario principal que posee el menú que ha creado. Uno de los atributos del formulario se llama .Menu . Si el menú se creó mediante progtwigción, debería ser el mismo, y se reconocería como un menú y se colocaría en el atributo de menú del formulario.

En este caso, tenía un menú principal llamado File . Un submenú, llamado MenuItem en File contenía la etiqueta Open y se llamaba menu_File_Open . Lo siguiente funcionó. Asumiéndote

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

Una de las mejores maneras es una sola fila de código como esta:

En este ejemplo buscamos todo PictureBox por nombre en un formulario

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

Lo más importante es el segundo parámetro de find .

si está seguro de que existe el nombre de control, puede usarlo directamente:

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

Usando el mismo enfoque de Philip Wallace , podemos hacer esto:

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

Ejemplo:

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

¡Espero que ayude! 🙂

Eche un vistazo a la colección ToolStrip.Items. Incluso tiene un método de búsqueda disponible.

Puedes hacer lo siguiente:

 private ToolStripMenuItem getToolStripMenuItemByName (string nameParam)
    {
       foreach (Control ctn en this.Controls)
          {
             if (ctn es ToolStripMenuItem)
                {
                    if (ctn.Name = nameParam)
                       {
                          devolver ctn;
                       }
                 }
          }
          devolver nulo;
     }

Una solución simple sería iterar a través de la lista de Controls en un bucle foreach . Algo como esto:

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

Entonces ahora tienes tu iterador, child , que es de tipo Control . Ahora haz lo que quieras con eso, personalmente lo encontré en un proyecto que hice hace un tiempo en el que agregó un evento para este control, como este:

 child.MouseDown += new MouseEventHandler(dragDown);