【问题标题】:Find a control in Windows Forms by name按名称在 Windows 窗体中查找控件
【发布时间】:2011-05-27 21:39:19
【问题描述】:

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

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

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

当父母知道时,上述方法很有帮助。在我的场景中,只知道要访问的对象的名称 [button1] 而不是它的父对象。那么我如何通过它的名字访问这个对象,而不是它的父对象呢?

有没有类似 GetObject("objName") 之类的方法?

【问题讨论】:

    标签: c# winforms controls


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 搜索是否区分大小写?
      【解决方案3】:
        TextBox txtAmnt = (TextBox)this.Controls.Find("txtAmnt" + (i + 1), false).FirstOrDefault();
      

      当您知道自己在寻找什么时,这很有效。

      【讨论】:

      • 表达式中的 +1 让我免于出现错误!
      【解决方案4】:

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

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

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

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

      然后像这样使用它:

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

      【讨论】:

        猜你喜欢
        • 2011-04-23
        • 1970-01-01
        • 2010-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多