Reputation: 707
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 regards.
**
**
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.
Upvotes: 2
Views: 3885
Reputation: 1835
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;
}
}
}
Upvotes: 0
Reputation: 1734
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;
}
}
}
}
Upvotes: 1
Reputation: 155692
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.
Upvotes: 0
Reputation: 1062855
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 Control
s); 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?
Upvotes: 20
Reputation: 166396
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#
Upvotes: 13
Reputation: 234474
Why don't you just use the Controls property of the form?
foreach(var control in form.Controls)
{
// Do something with the thing
}
Upvotes: 2