我有一个名为“MYMENU” ToolStripMenuItem。 我怎么可以访问此像这样:
/* Normally, I would do: */
this.myMenu... etc.
/* But how do I access it like this: */
String name = myMenu;
this.name...
这是因为我是动态地从一个XML文件生成ToolStripMenuItems,需要通过动态生成的名字引用的菜单项。
我有一个名为“MYMENU” ToolStripMenuItem。 我怎么可以访问此像这样:
/* Normally, I would do: */
this.myMenu... etc.
/* But how do I access it like this: */
String name = myMenu;
this.name...
这是因为我是动态地从一个XML文件生成ToolStripMenuItems,需要通过动态生成的名字引用的菜单项。
使用Control.ControlCollection.Find方法。
试试这个:
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;
}
忽略此,我重塑轮子。
假设你拥有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
重复。
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));
}
}
}
既然你是动态生成它们,保持一个字符串,菜单项,这将允许快速检索之间的映射。
// 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>"];
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;
}
假设你有Windows.Form Form1
作为拥有你所创建的菜单的父窗体。 一个窗体的属性命名.Menu
。 如果菜单以编程方式创建的,它应该是相同的,它会被认为是一个菜单,并放置在窗体的菜单属性。
在这种情况下,我只好叫主菜单File
。 子菜单,称为MenuItem
下File
包含的标签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;
使用同样的方法菲利普·华莱士 ,我们可以这样做:
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!";
}
我希望它能帮助! :)
其中最好的办法是这样的代码的单个行:
在这个例子中,我们搜索所有PictureBox
的名字的形式
PictureBox[] picSample =
(PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true);
最重要的是第二paramenter find
。
如果您确信该控件的名称存在,你可以直接使用它:
PictureBox picSample =
(PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true)[0];
看一看在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; }
一个简单的解决办法是通过迭代Controls
列表中foreach
循环。 事情是这样的:
foreach (Control child in Controls)
{
// Code that executes for each control.
}
所以,现在你有你的迭代, child
,这是类型的Control
。 现在做什么,你将用,我个人发现这一个项目,我做了,而以前在其中添加了事件的这种控制,就像这样:
child.MouseDown += new MouseEventHandler(dragDown);