我有一个主要表单(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的内容时,我想要所有“信息”。
一些建议??
最好的问候。
**
**
好的,我做了一个测试项目。在那里你可以看到我想做什么。在项目中是一个带有对象的图像...... 在这里你可以下载它: http://www.mediafire.com/download.php?ik5j3ejnzm2
最好的问候。
答案 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)
{
}
}
}
看看这个
答案 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;
}
}
}