C# 在C中按名称获取Windows窗体控件#

C# 在C中按名称获取Windows窗体控件#,c#,winforms,string,controls,accessibility,C#,Winforms,String,Controls,Accessibility,我有一个名为myMenu的ToolStripMenuItem。我如何才能这样访问此文件: /* Normally, I would do: */ this.myMenu... etc. /* But how do I access it like this: */ String name = myMenu; this.name... 这是因为我正在从XML文件动态生成ToolStripMenuItems,需要通过动态生成的名称引用MenuItems。使用该方法 试试这个: this.Cont

我有一个名为
myMenu
ToolStripMenuItem
。我如何才能这样访问此文件:

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

/* But how do I access it like this: */
String name = myMenu;
this.name...
这是因为我正在从XML文件动态生成ToolStripMenuItems,需要通过动态生成的名称引用MenuItems。

使用该方法

试试这个:

this.Controls.Find()

忽略这一点,我重新发明了控制盘。

因为您是动态生成它们的,所以在字符串和菜单项之间保留一个映射,这样可以快速检索

// 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>"];
//在类范围内
专用只读词典_menuItemsByName=新词典();
//在创建项目的方法中
ToolStripMenuItem createdItem=。。。
_menuItemsByName.Add(“,createdItem);
//访问它
ToolStripMenuItem menuItem=_menuItemsByName[“”];

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

您可以执行以下操作:

private ToolStripMenuItem getToolStripMenuItemByName(string nameParam) { foreach (Control ctn in this.Controls) { if (ctn is ToolStripMenuItem) { if (ctn.Name = nameParam) { return ctn; } } } return null; } 专用工具StripMenuItem getToolStripMenuItemByName(字符串名称参数) { foreach(此控件中的控件ctn) { if(ctn为ToolStripMenuItem) { 如果(ctn.Name=nameParam) { 返回ctn; } } } 返回null; } 这是实际运行的代码:

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:

公共控件[]查找(字符串键,bool searchAllChildren)
{
if(string.IsNullOrEmpty(key))
{
抛出新的ArgumentNullException(“key”,SR.GetString(“FindKeyNotBeemptyorNull”);
}
ArrayList list=this.FindInternal(key,searchAllChildren,this,new ArrayList());
Control[]数组=新控件[list.Count];
list.CopyTo(数组,0);
返回数组;
}
私有ArrayList FindInternal(字符串键、bool searchAllChildren、Control.ControlCollection controlsToLookIn、ArrayList foundControls)
{
if((controlsToLookIn==null)| |(foundControls==null))
{
返回null;
}
尝试
{
for(int i=0;i0))
{
foundControls=this.FindInternal(键,searchAllChildren,controlsToLookIn[j].Controls,foundControls);
}
}
}
捕获(异常)
{
if(ClientUtils.IsSecurityOrCriticalException(异常))
{
投掷;
}
}
返回控制;
}
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)); 
        }
     }
  }

假设您有
menuStrip
对象,并且菜单只有一级深度,请使用:

ToolStripMenuItem item = menuStrip.Items
    .OfType<ToolStripMenuItem>()
    .SelectMany(it => it.DropDownItems.OfType<ToolStripMenuItem>())
    .SingleOrDefault(n => n.Name == "MyMenu");
ToolStripMenuItem=menuStrip.Items
第()类
.SelectMany(it=>it.DropDownItems.OfType())
.SingleOrDefault(n=>n.Name==“MyMenu”);
对于更深的菜单级别,请在语句中添加更多SelectMany运算符

如果要搜索条带中的所有菜单项,请使用

ToolStripMenuItem item = menuStrip.Items
    .Find("MyMenu",true)
    .OfType<ToolStripMenuItem>()
    .Single();
ToolStripMenuItem=menuStrip.Items
.Find(“我的菜单”,真)
第()类
.Single();
但是,请确保每个菜单具有不同的名称,以避免重复键引发异常


为了避免异常,您可以使用
FirstOrDefault
而不是
SingleOrDefault
/
Single
,或者如果您可能有
Name
重复项,则只返回一个序列。

假设您有
Windows.Form1
作为拥有所创建菜单的父窗体。表单的一个属性名为
.Menu
。如果菜单是以编程方式创建的,那么它应该是相同的,并且它将被识别为菜单并放置在表单的menu属性中

在本例中,我有一个名为
File
的主菜单。
File
下名为
MenuItem
的子菜单包含标签
Open
,名为
menu File\u 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;

一个简单的解决方案是在
foreach
循环中迭代
控件
列表。大概是这样的:

foreach (Control child in Controls)
{
    // Code that executes for each control.
}
child.MouseDown += new MouseEventHandler(dragDown);
    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;
    }
现在有了迭代器,
child
,它的类型是
Control
。现在做你想做的,我个人在我之前做的一个项目中发现了这个,在这个项目中,它为这个控件添加了一个事件,如下所示:

foreach (Control child in Controls)
{
    // Code that executes for each control.
}
child.MouseDown += new MouseEventHandler(dragDown);
    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;
    }

使用相同的方法,我们可以这样做:

foreach (Control child in Controls)
{
    // Code that executes for each control.
}
child.MouseDown += new MouseEventHandler(dragDown);
    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!";
    }

我希望它能有所帮助!:)

最好的方法之一是一行代码,如下所示:

foreach (Control child in Controls)
{
    // Code that executes for each control.
}
child.MouseDown += new MouseEventHandler(dragDown);
    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;
    }
在本例中,我们在表单中按名称搜索所有
PictureBox

PictureBox[] picSample = 
                    (PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true);
最重要的是
find
的第二个参数

如果确定控件名称存在,则可以直接使用它:

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

您可以在表单类中使用find函数。如果要强制转换(标签),(文本视图)。。。等等,通过这种方式,您可以使用对象的特殊功能。它将是返回标签对象

(Label)this.Controls.Find(name,true)[0];
名称:表单中搜索项目的项目名称


true:搜索所有子项布尔值

这不适用于我。我认为这是因为,正如o3o所指出的,ToolStripMenuItem不是控件。对于textbox,我必须转换为控件类型,并采用如下第一个元素:
((textbox)frm.Controls.Find(“controlName”,true)[0])。Text=“yay”
@DanW这很像Java如果我有名字的一部分,我需要一个名字中有字符串的控件列表怎么办?现在有个主意了+1(尽管仅当控件已在字典中时才起作用)更一般