开发者

Form to object and loop through objects in c#?

I have a main form (frmMain), with some buttons (button1, button2...).

then I do this:

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

how could I loop through all containing items in my object to access butto1, button2...???

I did this, but it's not what I want.

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

I want to do something like this:

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

When I'm debuggin and looking at the content of objectsContainer there are all "infos" that I want.

Some suggestions??

Best r开发者_如何转开发egards.

**

UPDATE:

**

OK, I made a test project. There you could see what I want to do. In the project is an image with the objects... Here you can download it: http://www.mediafire.com/download.php?ik5j3ejnzm2

Best regards.


Each Control has a Controls collection that you can iterate through to get the full hierarchy, but unfortunately ToolStrip items use a different object model (they aren't all Controls); as such, you can iterate such a setup (to include the menu items too), but it isn't trivial; here's an example:

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

You might call this, for example, via something like:

    foreach (object obj in RecurseObjects(this)) {
        Console.WriteLine(obj);
    }

Of course, then the question is: what do you want to do with each item?


You can loop the ControlCollection.

Just remember that these controls can be nested, if they are in panels eg.

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

Have a look at this

Find a control recursively in C#


Why don't you just use the Controls property of the form?

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


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


How about this (similar to other answers but simple and easy to use):

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

I've got a utility function like this that I use quite often.


I decided to give this a try. I downloaded your sample app and modified your main form to include the algorithm I think you have asked for. Hope this helps:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜