可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a ToolStripMenuItem called \"myMenu\". How can I access this like so:
/* Normally, I would do: */
this.myMenu... etc.
/* But how do I access it like this: */
String name = myMenu;
this.name...
This is because I am dynamically generating ToolStripMenuItems from an XML file and need to reference menuitems by their dynamically generated names.
回答1:
Use the Control.ControlCollection.Find method.
Try this:
this.Controls.Find()
回答2:
string name = \"the_name_you_know\";
Control ctn = this.Controls[name];
ctn.Text = \"Example...\";
回答3:
Control GetControlByName(string Name)
{
foreach(Control c in this.Controls)
if(c.Name == Name)
return c;
return null;
}
Disregard this, I reinvent wheels.
回答4:
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.
回答5:
this.Controls.Find(name, searchAllChildren) doesn\'t find ToolStripItem because ToolStripItem is not a Control
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));
}
}
}
回答6:
Since you\'re generating them dynamically, keep a map between a string and the menu item, that will allow fast retrieval.
// 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>\"];
回答7:
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;
}
回答8:
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;
回答9:
One of the best way is a single row of code like this:
In this example we search all PictureBox
by name in a form
PictureBox[] picSample =
(PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true);
Most important is the second paramenter of find
.
if you are certain that the control name exists you can directly use it:
PictureBox picSample =
(PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true)[0];
回答10:
Using the same approach of Philip Wallace, we can do like this:
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;
}
Example:
public void doSomething()
{
TextBox myTextBox = (TextBox) this.GetControlByName(this, \"mytextboxname\");
myTextBox.Text = \"Hello!\";
}
I hope it help! :)
回答11:
Have a look at the ToolStrip.Items collection. It even has a find method available.
回答12:
You can do the following:
private ToolStripMenuItem getToolStripMenuItemByName(string nameParam)
{
foreach (Control ctn in this.Controls)
{
if (ctn is ToolStripMenuItem)
{
if (ctn.Name = nameParam)
{
return ctn;
}
}
}
return null;
}
回答13:
A simple solution would be to iterate through the Controls
list in a foreach
loop. Something like this:
foreach (Control child in Controls)
{
// Code that executes for each control.
}
So now you have your iterator, child
, which is of type Control
. Now do what you will with that, personally I found this in a project I did a while ago in which it added an event for this control, like this:
child.MouseDown += new MouseEventHandler(dragDown);