web-dev-qa-db-ja.com

C#でWindowsフォームコントロールを名前で取得する

「myMenu」というToolStripMenuItemがあります。どうすればこれにアクセスできますか:

/* Normally, I would do: */
this.myMenu... etc.

/* But how do I access it like this: */
String name = myMenu;
this.name...

これは、XMLファイルからToolStripMenuItemsを動的に生成しており、動的に生成された名前でメニュー項目を参照する必要があるためです。

57
user186249

Control.ControlCollection.Find メソッドを使用します。

これを試して:

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;
}

これを無視して、車輪を再発明します。

9

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が重複する可能性がある場合は単にシーケンスを返します。

6
dmihailescu

this.Controls.Find(name、searchAllChildren)はToolStripItemを検出しませんToolStripItemは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)); 
        }
     }
  }
4
o3o

Windows.Form Form1作成したメニューを所有する親フォームとして。フォームの属性の1つは.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;
3
shooky56
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;
    }
}

対:

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

Philip Wallace と同じアプローチを使用すると、次のようにできます。

    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!";
    }

お役に立てば幸いです! :)

3
V1NNY

最良の方法の1つは、次のような1行のコードです。

この例では、すべてのPictureBoxをフォーム内の名前で検索します

PictureBox[] picSample = 
                    (PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true);

最も重要なのは、findの2番目のパラメーターです。

コントロール名が存在することが確実な場合は、直接使用できます。

  PictureBox picSample = 
                        (PictureBox)this.Controls.Find(PIC_SAMPLE_NAME, true)[0];
3
daniele3004

それらを動的に生成しているため、文字列とメニュー項目の間にマップを保持しておくと、高速で取得できます。

// 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

ToolStrip.Itemsコレクションをご覧ください。 findメソッドも利用できます。

0
Neil

簡単な解決策は、Controlsループ内のforeachリストを反復処理することです。このようなもの:

foreach (Control child in Controls)
{
    // Code that executes for each control.
}

これで、child型のイテレータControlができました。今、あなたはそれであなたがすることをします、個人的に私はこの前に私がこのコントロールのイベントを追加したプロジェクトで見つけました:

child.MouseDown += new MouseEventHandler(dragDown);
0
carefulnow1

次のことができます。

 private ToolStripMenuItem getToolStripMenuItemByName(string nameParam)
 {
 foreach(this.Controlsのコントロールctn)
 {
 if(ctnがToolStripMenuItem)
 {
 if(ctn.Name = nameParam)
 {
 return ctn; 
} 
} 
} 
 nullを返す; 
} 
0
Koekiebox

Formクラスで検索機能を使用できます。 (Label)、(TextView)...などをキャストする場合は、この方法でオブジェクトの特別な機能を使用できます。返されるLabelオブジェクトになります。

(Label)this.Controls.Find(name,true)[0];

name:フォーム内の検索されたアイテムのアイテム名

true:すべての子ブール値を検索

0
Ferhat KOÇER