Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
窗体到对象并在c#中循环对象?_C#_.net_Winforms_Object - Fatal编程技术网

窗体到对象并在c#中循环对象?

窗体到对象并在c#中循环对象?,c#,.net,winforms,object,C#,.net,Winforms,Object,我有一个主窗体(frmMain),带有一些按钮(按钮1,按钮2…) 然后我会这样做: object objectsContainer = frmMain; // <--now the object contains form base, button1, button2... 我想这样做: foreach (object objectFromForm in objectsContainer) // <--- how to do this looping an object

我有一个主窗体
(frmMain)
,带有一些按钮
(按钮1,按钮2…

然后我会这样做:

object objectsContainer = frmMain; // <--now the object contains form base, button1, button2...
我想这样做:

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

foreach(objectscocontainer中的objectFromForm)//为什么不使用表单的属性呢

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

您可以循环ControlCollection

只要记住,这些控件可以嵌套,如果它们在面板中,例如

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


每个
控件
都有一个
控件
集合,您可以通过该集合进行迭代以获得完整的层次结构,但不幸的是
ToolStrip
项使用不同的对象模型(它们并不都是
控件
s);因此,您可以迭代这样的设置(也包括菜单项),但这并不是一件小事;下面是一个例子:

    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);
                }
            }
        }            
    }
例如,您可以通过以下方式将其称为:

    foreach (object obj in RecurseObjects(this)) {
        Console.WriteLine(obj);
    }
当然,接下来的问题是:您想对每个项目做什么?

public IEnumerable Get(对象o)
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;
            }
        }  
    }  
}
{ if(o是System.Windows.Forms.Control) { System.Windows.Forms.Control f=(System.Windows.Forms.Control)o; foreach(f.Controls中的System.Windows.Forms.Control c) { 收益率c; foreach(Get(c)中的System.Windows.Forms.Control c2) { 收益率c2; } } } }
这个如何(与其他答案类似,但简单易用):

使用System.Windows.Forms;
公共静态类控件扩展
{
公共IEnumerable子代控件(此控件)
{   
foreach(control.Controls中的var子级)
{  
退换子女;
foreach(child.degenantControls()中的var后代)
{
产量回报后代;
}
}
}
}

我有一个这样的实用函数,我经常使用。

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

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;
      }
   }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
名称空间测试
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
//如果调试此代码,则对象将保存此窗体上的所有控件
对象=这个;
Dictionary allControls=GetIt(对象);
}
/// 
///如果可用(包括此表单),如何获取所有控件名称和.Text值???
/// 
私有字典GetIt(对象)
{
已找到字典=新字典();
队列控制队列=新队列();
排队(对象作为控件);
while(controlQueue.Count>0)
{
控制项=controlQueue.Dequeue();
foreach(item.Controls中的控件ctrl)
{
controlQueue.Enqueue(ctrl);
}
找到.添加(项,项.文本);
}
发现退货;
}
}
}

Ow,这里出现了一些严重的混乱……您不需要将表单向上转换为object来使用任何东西。这样做实际上会失去功能。您可以将其直接用作
frmMain
。我想你应该多读一些关于OO和.NET类型系统的书。你是怎么做的?这仍然是个问题吗?也许可以澄清一下你所需要的和提供的答案之间的差距……你可以通过悬赏获得比你更高的声誉?不,如果你阅读常见问题解答,stackoverflow会增加你50%的“赌注”。因为:form.Controls只返回toolstrip控件,而不返回toolstrip中的其他控件。避免占用太多堆栈空间-p@behrooz-它确实使用了
收益率回报
;它没有做的是在堆栈上自递归以获取子控件,这实际上是非常浪费的;如果(f!=null).
我只想使用“yield return”语句,而不使用“Queue”。你好,Keith,我尝试了您的解决方案,但出现错误:foreach语句无法对“System.Collections.Generic.IEnumerator”类型的变量进行操作,因为“System.Collections.Generic.IEnumerator”不包含“GetEnumerator”的公共定义返回类型应为
IEnumerable
,而不是
IEnumerator
如何使用此代码?我在主窗体中添加了它,但得到了一个错误:扩展方法必须在非泛型静态类更新示例中定义-这需要在它自己的静态类中定义。您将能够执行foreach(frmMain.genderantcontrols()中的var ctrl){…谢谢Mark。接近完美的只是一件小事…如何获得所有菜单项,如menu22 ToolStripMenuItem=“Menu2.2”和其他子项,如text1ToolStripMenuItem=“text1”还有组合框文本项?alives.ummm。我想你需要反射才能找到控件集合。我再试试。
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;
            }
        }
    }
}
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;
      }
   }
}