Get a Windows Forms control by name in C#

后端 未结 14 1537
野性不改
野性不改 2020-11-22 09:22

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

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

/* But ho         


        
相关标签:
14条回答
  • 2020-11-22 09: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.

    0 讨论(0)
  • 2020-11-22 10:05
    string name = "the_name_you_know";
    
    Control ctn = this.Controls[name];
    
    ctn.Text = "Example...";
    
    0 讨论(0)
  • 2020-11-22 10:05
    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;
    }
    
    0 讨论(0)
  • 2020-11-22 10:05

    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;
    
    0 讨论(0)
  • 2020-11-22 10:05

    You can use find function in your Form class. If you want to cast (Label) ,(TextView) ... etc, in this way you can use special features of objects. It will be return Label object.

    (Label)this.Controls.Find(name,true)[0];
    

    name: item name of searched item in the form

    true: Search all Children boolean value

    0 讨论(0)
  • 2020-11-22 10:06

    Use the Control.ControlCollection.Find method.

    Try this:

    this.Controls.Find()
    
    0 讨论(0)
提交回复
热议问题