Ich habe ein ToolStripMenuItem mit dem Namen "myMenu". Wie kann ich so darauf zugreifen:
/* Normally, I would do: */
this.myMenu... etc.
/* But how do I access it like this: */
String name = myMenu;
this.name...
Dies liegt daran, dass ich ToolStripMenuItems dynamisch aus einer XML-Datei generiere und auf Menüelemente anhand ihrer dynamisch generierten Namen verweisen muss.
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;
}
Ignoriere das, ich erfinde Räder neu.
Angenommen, Sie haben das Objekt menuStrip
und das Menü ist nur eine Ebene tief. Verwenden Sie:
ToolStripMenuItem item = menuStrip.Items
.OfType<ToolStripMenuItem>()
.SelectMany(it => it.DropDownItems.OfType<ToolStripMenuItem>())
.SingleOrDefault(n => n.Name == "MyMenu");
Für tiefere Menüebenen fügen Sie der Anweisung weitere SelectMany-Operatoren hinzu.
wenn Sie alle Menüpunkte in der Leiste durchsuchen möchten, verwenden Sie
ToolStripMenuItem item = menuStrip.Items
.Find("MyMenu",true)
.OfType<ToolStripMenuItem>()
.Single();
Stellen Sie jedoch sicher, dass jedes Menü einen anderen Namen hat, um Ausnahmen durch doppelte Schlüssel zu vermeiden.
Um Ausnahmen zu vermeiden, können Sie FirstOrDefault
anstelle von SingleOrDefault
/Single
verwenden oder einfach eine Sequenz zurückgeben, wenn Sie möglicherweise Name
Duplikate haben.
this.Controls.Find (name, searchAllChildren) findet ToolStripItem nicht, weil ToolStripItem kein Steuerelement ist
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));
}
}
}
Angenommen, Sie haben Windows.Form Form1
als übergeordnetes Formular, dem das von Ihnen erstellte Menü gehört. Eines der Attribute des Formulars heißt .Menu
. Wenn das Menü programmgesteuert erstellt wurde, sollte es identisch sein und als Menü erkannt und im Menüattribut des Formulars platziert werden.
In diesem Fall hatte ich ein Hauptmenü namens File
. Ein Untermenü namens MenuItem
unter File
enthielt das Tag Open
und wurde menu_File_Open
. Folgendes hat funktioniert. Ich nehme dich an
// 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;
this.Controls["name"];
Dies ist der eigentliche Code, der ausgeführt wird:
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;
}
Mit dem gleichen Ansatz von Philip Wallace können wir folgendermaßen vorgehen:
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;
}
Beispiel:
public void doSomething()
{
TextBox myTextBox = (TextBox) this.GetControlByName(this, "mytextboxname");
myTextBox.Text = "Hello!";
}
Ich hoffe es hilft! :)
Eine der besten Möglichkeiten ist eine einzelne Codezeile wie diese:
In diesem Beispiel durchsuchen wir alle PictureBox
nach Namen in einem Formular
PictureBox[] picSample =
(PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true);
Am wichtigsten ist der zweite Parameter von find
.
wenn Sie sicher sind, dass der Kontrollname existiert, können Sie ihn direkt verwenden:
PictureBox picSample =
(PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true)[0];
Da Sie sie dynamisch generieren, behalten Sie eine Zuordnung zwischen einer Zeichenfolge und dem Menüelement bei, um einen schnellen Abruf zu ermöglichen.
// 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>"];
Schauen Sie sich die ToolStrip.Items-Auflistung an. Es gibt sogar eine Suchmethode.
Eine einfache Lösung wäre, die Liste Controls
in einer foreach
-Schleife zu durchlaufen. Etwas wie das:
foreach (Control child in Controls)
{
// Code that executes for each control.
}
Nun haben Sie Ihren Iterator child
, der vom Typ Control
ist. Jetzt mach was du willst, persönlich fand ich das in einem Projekt, das ich vor einiger Zeit gemacht habe, in dem es ein Ereignis für dieses Steuerelement hinzufügte, so:
child.MouseDown += new MouseEventHandler(dragDown);
Sie können Folgendes tun:
privates ToolStripMenuItem getToolStripMenuItemByName (ZeichenfolgenameParam) .____.] { if (ctn.Name = nameParam) { return ctn; } } } return null; }
Sie können die Suchfunktion in Ihrer Form-Klasse verwenden. Wenn Sie (Label), (TextView) ... usw. umwandeln möchten, können Sie auf diese Weise spezielle Funktionen von Objekten verwenden. Es wird Label-Objekt zurückgeben.
(Label)this.Controls.Find(name,true)[0];
name: Artikelname des gesuchten Artikels im Formular
true: Durchsucht alle untergeordneten booleschen Werte