获得在C#中的名字一个Windows窗体控件(Get a Windows Forms control

2019-07-21 10:27发布

我有一个名为“MYMENU” ToolStripMenuItem。 我怎么可以访问此像这样:

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

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

这是因为我是动态地从一个XML文件生成ToolStripMenuItems,需要通过动态生成的名字引用的菜单项。

Answer 1:

使用Control.ControlCollection.Find方法。

试试这个:

this.Controls.Find()


Answer 2:

string name = "the_name_you_know";

Control ctn = this.Controls[name];

ctn.Text = "Example...";


Answer 3:

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

    return null;
}

忽略此,我重塑轮子。



Answer 4:

假设你拥有menuStrip对象和菜单的深度仅为1级,使用方法:

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

对于更深层次的菜单在声明中增加更多的运营商的SelectMany。

如果你想在搜索条的所有菜单项,然后使用

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

然而,要确保每个菜单都有不同的名称,以避免异常的关键重复抛出。

为了避免异常,您可以使用FirstOrDefault代替SingleOrDefault / Single ,或只返回一个序列,如果你可能有Name重复。



Answer 5:

this.Controls.Find(姓名,searchAllChildren)未找到的ToolStripItem因为ToolStripItem的不是控制

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


Answer 6:

既然你是动态生成它们,保持一个字符串,菜单项,这将允许快速检索之间的映射。

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


Answer 7:

this.Controls["name"];

这是实际的代码,然:

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


Answer 8:

假设你有Windows.Form Form1作为拥有你所创建的菜单的父窗体。 一个窗体的属性命名.Menu 。 如果菜单以编程方式创建的,它应该是相同的,它会被认为是一个菜单,并放置在窗体的菜单属性。

在这种情况下,我只好叫主菜单File 。 子菜单,称为MenuItemFile包含的标签Open并命名为menu_File_Open 。 下面的工作。 假设你

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


Answer 9:

使用同样的方法菲利普·华莱士 ,我们可以这样做:

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

例:

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

我希望它能帮助! :)



Answer 10:

其中最好的办法是这样的代码的单个行:

在这个例子中,我们搜索所有PictureBox的名字的形式

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

最重要的是第二paramenter find

如果您确信该控件的名称存在,你可以直接使用它:

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


Answer 11:

看一看在ToolStrip.Items集合。 它甚至有一个可用的查找方法。



Answer 12:

你可以做到以下几点:

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


Answer 13:

一个简单的解决办法是通过迭代Controls列表中foreach循环。 事情是这样的:

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

所以,现在你有你的迭代, child ,这是类型的Control 。 现在做什么,你将用,我个人发现这一个项目,我做了,而以前在其中添加了事件的这种控制,就像这样:

child.MouseDown += new MouseEventHandler(dragDown);


文章来源: Get a Windows Forms control by name in C#