按名称在Windows窗体中查找控件

我正在开发一个应用程序,它在运行时从XML文件添加对象(基本上是Windows窗体控件)。 应用程序需要访问已添加的对象。

对象将添加到面板或组框中。 对于面板和组框,我有Panel.Controls [“object_name”]来访问对象。 这仅在将对象直接添加到同一面板上时才有用。 在我的情况下,主面板[pnlMain,我只能访问此面板]可能包含另一个面板,此面板[pnlChild]再次包含一个groupbox [gbPnlChild],groupbox包含一个按钮[button1,我想访问此按钮] 。 我有以下方法:

Panel childPanel = pnlMain.Controls["pnlChild"]; GroupBox childGP = childPanel.Controls["gbPnlChild"]; Button buttonToAccess = childGP["button1"]; 

当父母知道时,上述方法很有用。 在我的场景中,只知道要访问的对象的名称[button1]而不是其父对象。 那么如何通过名称访问此对象,与其父对象无关?

是否有像GetObject(“objName”)或类似的方法?

您可以使用表单的Controls.Find()方法来检索引用:

  var matches = this.Controls.Find("button2", true); 

请注意,这会返回一个数组 ,控件的Name属性可能不明确,没有任何机制可以确保控件具有唯一的名称。 你必须自己强制执行。

  TextBox txtAmnt = (TextBox)this.Controls.Find("txtAmnt" + (i + 1), false).FirstOrDefault(); 

当你知道你在寻找什么时,这就有效。

如果您在用户控件中并且无法直接访问容器表单,则可以执行以下操作

 var parent = this.FindForm(); // returns the object of the form containing the current usercontrol. var findButton = parent.Controls.Find("button1",true).FirstOfDefault(); if(findButton!=null) { findButton.Enabled =true; // or whichever property you want to change. } 

.NET Compact Framework不支持Control.ControlCollection.Find。

请参阅Control.ControlCollection方法并注意Find方法旁边没有小电话图标。

在这种情况下,请定义以下方法:

 // Return all controls by name // that are descendents of a specified control. List GetControlByName( Control controlToSearch, string nameOfControlsToFind, bool searchDescendants) where T : class { List result; result = new List(); foreach (Control c in controlToSearch.Controls) { if (c.Name == nameOfControlsToFind && c.GetType() == typeof(T)) { result.Add(c as T); } if (searchDescendants) { result.AddRange(GetControlByName(c, nameOfControlsToFind, true)); } } return result; } 

然后像这样使用它:

 // find all TextBox controls // that have the name txtMyTextBox // and that are descendents of the current form (this) List targetTextBoxes = GetControlByName(this, "txtMyTextBox", true);