窗体到对象并在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;
}
}
}