在tabcontrol上循环访问datagridviews [英] Loop through datagridviews on a tabcontrol

查看:73
本文介绍了在tabcontrol上循环访问datagridviews的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个6页的TabControl。每个页面都有一个带有DataGridView的GroupBox。

我需要遍历所有6个DataGridViews作为单元验证例程的一部分。



我尝试了什么:



我已经创建了这个代码来查找所有的DGV,所以我可以遍历它们但它没有似乎找不到任何DGV。

 foreach(Data.GridView中的DataGridView dgv< DataGridView>())
{
}

还尝试了

 foreach(this.Controls.OfType中的DataGridView dgv< DataGridView>())

这也是一个失败。



我可以通过这个代码深入了解各个控件集合中的DGV,但它看起来非常复杂。当然有一种更简单的方法吗?

 foreach(在此.tabControl1.Controls中控制c)
{
if(c is TabPage)
{
foreach(控制d在c.​​Controls中)
{
如果(d是GroupBox)
{
foreach(控制e在d.Controls中)
{
if(e是DataGridView)
{
DataGridView dgv =(DataGridView)e;
//处理DGV
}
}
}
}
}
}







我缺少什么?

解决方案

你需要深入研究;我使用Linq:

 private List< DataGridView> DGViews; 

private void Form1_Load(object sender,EventArgs e)
{
DGViews = tabControl1.TabPages
.Cast< TabPage>()
.SelectMany( (TabPage选项卡)=> tab.Controls.OfType< DataGridView>())
.ToList();
}

由于每次调用'OfType都会返回一个IEnumerable,因此使用'SelectMany会正确枚举这些中间结果。



您可以使用'Controls.Find,它可以选择递归,但它会搜索Control的key / name属性:您不能使用它来获取相同类型的所有控件。


这是我在这种情况下有用的辅助方法:

  public  < span class =code-keyword> static   class  TreeExtensions 
{
public static IEnumerable< T> SelectRecursive< T>( IEnumerable< T>来源,Func< T,IEnumerable< T>> getChildren)
{
if (source null throw new ArgumentNullException( nameof (source));
if (getChildren null throw new ArgumentNullException( nameof (的getChildren));
return Iterator();

IEnumerable< T> Iterator()
{
var stack = new Stack< IEnumerator< T> >();
尝试
{
stack.Push(source.GetEnumerator());
while (stack.Count!= 0
{
var iter = stack.Peek();
if (iter.MoveNext())
{
var current = iter.Current;
yield return current;

var children = getChildren(current);
if (children!= null )stack.Push(children.GetEnumerator());
}
else
{
iter.Dispose();
stack.Pop();
}
}
}
最后
{
while (stack.Count!= 0
{
stack.Pop()。Dispose();
}
}
}
}
}



有了这个,你现在可以搜索你的整个控制树使用LINQ:

 IEnumerable< DataGridView> dataGrids =  this  .Controls.Cast< Control>()
.SelectRecursive(c = > c.HasChildren?c.Controls.Cast< Control>(): null
.OfType< DataGridView>();


I have a TabControl with 6 pages. Each page has a GroupBox with a DataGridView on it.
I need to loop through all 6 DataGridViews as part of a cell validation routine.

What I have tried:

I've created this code to find all the DGV's so I can loop through them but it does not seem to find any DGV's at all.

foreach (DataGridView dgv in this.tabControl1.Controls.OfType<DataGridView>())
{
}

Also tried

foreach (DataGridView dgv in this.Controls.OfType<DataGridView>())

which is also a failure.

I can find the DGV's with this code drilling down through the individual control collections but it seems ridiculously complicated. Surely there is a simpler way?

foreach (Control c in this.tabControl1.Controls)
       {
           if (c is TabPage)
           {
               foreach (Control d in c.Controls)
               {
                   if (d is GroupBox)
                   {
                       foreach (Control e in d.Controls)
                       {
                           if (e is DataGridView)
                           {
                               DataGridView dgv = (DataGridView)e;
                                // process the DGVs
                           }
                       }
                   }
               }
           }
       }




What am I missing?

解决方案

You gotta drill-down; I'd use Linq:

private List<DataGridView> DGViews;

private void Form1_Load(object sender, EventArgs e)
{
    DGViews = tabControl1.TabPages
        .Cast<TabPage>()
        .SelectMany((TabPage tab) => tab.Controls.OfType<DataGridView>())
        .ToList();
}

Since every call to 'OfType returns an IEnumerable, the use of 'SelectMany does the right thing to enumerate those intermediate results.

You can use 'Controls.Find which can optionally recurse, but it searches on the key/name property of a Control: you can''t use that to get all Controls of the same Type.


Here's a helper method I find useful in this sort of situation:

public static class TreeExtensions
{
    public static IEnumerable<T> SelectRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> getChildren)
    {
        if (source is null) throw new ArgumentNullException(nameof(source));
        if (getChildren is null) throw new ArgumentNullException(nameof(getChildren));
        return Iterator();
        
        IEnumerable<T> Iterator()
        {
            var stack = new Stack<IEnumerator<T>>();
            try
            {
                stack.Push(source.GetEnumerator());
                while (stack.Count != 0)
                {
                    var iter = stack.Peek();
                    if (iter.MoveNext())
                    {
                        var current = iter.Current;
                        yield return current;
                        
                        var children = getChildren(current);
                        if (children != null) stack.Push(children.GetEnumerator());
                    }
                    else
                    {
                        iter.Dispose();
                        stack.Pop();
                    }
                }
            }
            finally
            {
                while (stack.Count != 0)
                {
                    stack.Pop().Dispose();
                }
            }
        }
    }
}


With that in place, you can now search your entire control tree using LINQ:

IEnumerable<DataGridView> dataGrids = this.Controls.Cast<Control>()
    .SelectRecursive(c => c.HasChildren ? c.Controls.Cast<Control>() : null)
    .OfType<DataGridView>();


这篇关于在tabcontrol上循环访问datagridviews的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆