简体   繁体   English

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

[英]Find a control in Windows Forms by name

I am working on an application which add objects (basically Windows Forms controls) at run time from an XML file.我正在开发一个应用程序,它在运行时从 XML 文件添加对象(基本上是Windows 窗体控件)。 The application needs to access the objects that have been added.应用程序需要访问已添加的对象。

The objects are added in a panel or in a groupbox.对象被添加到面板或分组框中。 For the panel and groupbox, I have Panel.Controls["object_name"] to access the objects.对于面板和分组框,我有 Panel.Controls["object_name"] 来访问对象。 This is only helpful when the object is directly added on the same panel.这仅在对象直接添加到同一面板上时才有用。 In my case the main panel [pnlMain, I have access to this panel only] may contain another panel and this panel [pnlChild] again contains a groupbox[gbPnlChild] and the groupbox contains a button [button1, I want to access this button].在我的例子中,主面板 [pnlMain,我只能访问这个面板] 可能包含另一个面板,这个面板 [pnlChild] 再次包含一个 groupbox[gbPnlChild] 并且 groupbox 包含一个按钮 [button1,我想访问这个按钮] . I have the following method for this:我有以下方法:

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

The above method is helpful when parents are known.当父母知道时,上述方法是有帮助的。 In my scenario, only the name of the object is known that is to be accessed [button1] and not its parents.在我的场景中,只知道要访问的对象的名称 [button1] 而不是其父对象。 So how do I access this object by its name, irrelevant of its parent?那么我如何通过它的名称访问这个对象,而与它的父对象无关?

Is there a method like GetObject("objName") or something similar?有没有像 GetObject("objName") 或类似的方法?

You can use the form's Controls.Find() method to retrieve a reference back:您可以使用表单的Controls.Find()方法来检索引用:

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

Beware that this returns an array , the Name property of a control can be ambiguous, there is no mechanism that ensures that a control has a unique name.请注意,这将返回一个数组,控件的 Name 属性可能不明确,没有确保控件具有唯一名称的机制。 You'll have to enforce that yourself.你必须自己强制执行。

If you are in a user control and don't have direct access to container form you can do the following如果您在用户控件中并且不能直接访问容器表单,则可以执行以下操作

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

当您知道自己在寻找什么时,这会起作用。

The .NET Compact Framework does not support Control.ControlCollection.Find. .NET Compact Framework 不支持 Control.ControlCollection.Find。

See Control.ControlCollection Methods and note that there is no little phone icon beside the Find method.请参阅Control.ControlCollection 方法并注意 Find 方法旁边没有小电话图标。

In that case, define the following method:在这种情况下,定义以下方法:

// Return all controls by name 
// that are descendents of a specified control. 

List<T> GetControlByName<T>(
    Control controlToSearch, string nameOfControlsToFind, bool searchDescendants) 
    where T : class
{
    List<T> result;
    result = new List<T>();
    foreach (Control c in controlToSearch.Controls)
    {
        if (c.Name == nameOfControlsToFind && c.GetType() == typeof(T))
        {
            result.Add(c as T);
        }
        if (searchDescendants)
        {
            result.AddRange(GetControlByName<T>(c, nameOfControlsToFind, true));
        }
    }
    return result;
}

Then use it like this:然后像这样使用它:

// find all TextBox controls
// that have the name txtMyTextBox
// and that are descendents of the current form (this)

List<TextBox> targetTextBoxes = 
    GetControlByName<TextBox>(this, "txtMyTextBox", true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM