表单对象和循环遍历c#中的对象?

时间:2009-12-05 12:15:15

标签: c# .net winforms object

我有一个主要表单(frmMain),其中包含一些按钮(button1, button2...)

然后我这样做:

object objectsContainer = frmMain; // <--now the object contains form base, button1, button2...

我怎么能遍历我对象中所有包含项目以访问butto1,button2 ...... ???

我这样做了,但这不是我想要的。

foreach (PropertyInfo pInfo in objectsContainer.GetType().GetProperties())     
{

}

我想做这样的事情:

foreach (object objectFromForm in objectsContainer)     // <--- how to do this looping an object (type of form)
{
    //here is objectFromForm = base, button1, button2...
    foreach (PropertyInfo pInfo in objectFromForm .GetType().GetProperties())     
    {
               //here it's possible to access pInfo and its properties like size, name ...
    }
}

当我调试并查看objectsContainer的内容时,我想要所有“信息”。

一些建议??

最好的问候。

**

UPDATE:

**

好的,我做了一个测试项目。在那里你可以看到我想做什么。在项目中是一个带有对象的图像...... 在这里你可以下载它: http://www.mediafire.com/download.php?ik5j3ejnzm2

最好的问候。

6 个答案:

答案 0 :(得分:20)

每个Control都有一个Controls集合,您可以通过迭代来获取完整的层次结构,但不幸的是ToolStrip个项目使用不同的对象模型(它们不是全部{{1} }} S);因此,您可以迭代这样的设置(也包括菜单项),但这不是微不足道的;这是一个例子:

Control

您可以通过以下方式调用此方法:

    IEnumerable RecurseObjects(object root) {
        Queue items = new Queue();
        items.Enqueue(root);
        while (items.Count > 0) {
            object obj = items.Dequeue();
            yield return obj;
            Control control = obj as Control;
            if (control != null) {
                // regular controls and sub-controls
                foreach (Control item in control.Controls) {
                    items.Enqueue(item);
                }
                // top-level menu items
                ToolStrip ts = control as ToolStrip;
                if (ts != null) {
                    foreach(ToolStripItem tsi in ts.Items) {
                        items.Enqueue(tsi);
                    }
                }
            }
            // child menus
            ToolStripDropDownItem tsddi = obj as ToolStripDropDownItem;
            if (tsddi != null && tsddi.HasDropDownItems) {
                foreach (ToolStripItem item in tsddi.DropDownItems) {
                    items.Enqueue(item);
                }
            }
        }            
    }

当然,问题是:你想对每个项目做什么?

答案 1 :(得分:13)

您可以循环ControlCollection。

请记住,如果这些控件位于面板中,则可以嵌套这些控件。

private void RecusiceControls(ControlCollection controls)
        {
            foreach (Control control in controls)
            {
                RecusiceControls((ControlCollection)control.Controls);
                if (control is Button)
                {
                }
            }
        }

看看这个

Find a control recursively in C#

答案 2 :(得分:2)

为什么不直接使用表单的Controls属性?

foreach(var control in form.Controls)
{
     // Do something with the thing
}

答案 3 :(得分:1)

public IEnumerable<Control> Get (object o)  
{  
    if (o is System.Windows.Forms.Control)  
    {  
        System.Windows.Forms.Control f =(System.Windows.Forms.Control)o;  
        foreach(System.Windows.Forms.Control c in f.Controls)  
        {  
            yield return c;
            foreach(System.Windows.Forms.Control c2 in Get(c))  
            {
                yield return c2;
            }
        }  
    }  
}

答案 4 :(得分:0)

这个怎么样(类似于其他答案,但简单易用):

using System.Windows.Forms;

public static class ControlExtensions 
{
    public IEnumerable<Control> DescendantControls(this Control control)  
    {   
        foreach(var child in control.Controls)  
        {  
            yield return child;
            foreach(var descendant in child.DescendantControls())  
            {
                yield return descendant;
            }
        }
    }
}

我有一个像我这样经常使用的实用功能。

答案 5 :(得分:0)

我决定尝试一下。我下载了您的示例应用并修改了您的主表单,以包含我认为您要求的算法。希望这会有所帮助:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Test
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();

         //if you debug this code then the objects is holding all controls on this form
         object objects = this;

         Dictionary<Control, string> allControls = GetIt(objects);
      }

      /// <summary>
      /// How to get all control names an .Text values if availible (included this form)???
      /// </summary>
      private Dictionary<Control, string> GetIt(object objects)
      {
          Dictionary<Control, string> found = new Dictionary<Control, string>();
          Queue<Control> controlQueue = new Queue<Control>();
          controlQueue.Enqueue(objects as Control);

          while (controlQueue.Count > 0)
          {
              Control item = controlQueue.Dequeue();
              foreach (Control ctrl in item.Controls)
              {
                  controlQueue.Enqueue(ctrl);
              }
              found.Add(item, item.Text);
          }

          return found;
      }
   }
}