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(尽管仅当控件已在字典中时才起作用)更一般