it-swarm.com.de

Abrufen eines Windows Forms-Steuerelements nach Namen in C #

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.

57
user186249

Verwenden Sie die Control.ControlCollection.Find -Methode.

Versuche dies:

this.Controls.Find()
109
Adriaan Stander
string name = "the_name_you_know";

Control ctn = this.Controls[name];

ctn.Text = "Example...";
35
vaNIts
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.

9

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.

6
dmihailescu

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)); 
        }
     }
  }
4
o3o

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;
3
shooky56
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;
}
3
Philip Wallace

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! :)

3
V1NNY

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];
3
daniele3004

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>"];
3

Schauen Sie sich die ToolStrip.Items-Auflistung an. Es gibt sogar eine Suchmethode.

0
Neil

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);
0
carefulnow1

Sie können Folgendes tun:

 privates ToolStripMenuItem getToolStripMenuItemByName (ZeichenfolgenameParam) .____.] {
 if (ctn.Name = nameParam) 
 {
 return ctn; 
} 
} 
} 
 return null; 
} 
0
Koekiebox

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

0
Ferhat KOÇER