c# - 我可以使用 LINQ 获取某种类型的所有组件吗?

标签 c# linq clr

我是 C# 的新手,遇到了一些问题,我确信使用 LINQ 有一个很好的解决方案。

背景: 我继承了一个使用 CrystalReports 的项目,报告本身都有以统一方式关联的查看器表单 [包含组件/控件](我很确定它们是机器生成的),其中一个是组件源自包含数据库属性的 ​​ReportClass。数据库属性是区分出现在所有这些类中的方法 (Log_On_Database) 的唯一的东西。我想做的是创建一个公共(public)基类,用于搜索 ReportClass 的表单,并使用它来填充其本地数据库变量 w/属性的值,这样我就可以实现 Log_On_Database 在一个位置。

问题: 如何使用 LINQ 获取属于表单的所有组件(不仅仅是[仅]控件)并递归地获取那些控件(因此可以拥有自己的控件) )?

注意:List 中获得结果会很棒,因为我可以测试长度为 0(出现严重错误)、1(预期) ,或更多(然后我可以在那些奇怪的情况下做我需要做的事情)——即使这都是生成的代码,我也不相信它没有以非常痛苦的方式被修改.

最佳答案

到目前为止,我得到了这个:

    // Get all controls of a certain type:
    // http://stackoverflow.com/questions/3419159/how-to-get-all-child-controls-of-a-winform-of-a-specific-type-button-textbox
    public IEnumerable<Control> GetAll(Control control, Type type)
    {
        var controls = control.Controls.Cast<Control>();

        return controls.SelectMany(ctrl => GetAll(ctrl, type))
                                  .Concat(controls)
                                  .Where(c => c.GetType() == type);
    }

    protected ComponentCollection get_components(Component c)
    {
        Type parent = c.GetType();
        FieldInfo fieldInfo = parent.GetField("components", BindingFlags.Instance | BindingFlags.NonPublic);
        IContainer fieldData = (IContainer)fieldInfo.GetValue(components);

        return fieldData.Components;
    }

    protected void Log_On_Database()
    {
        // ReportClass decends from ReportDocument, which has the Database property we're interested in
        // this method grabs up any ReportDocument and decended objects. There should be only one.
        List<ReportDocument> reports = new List<ReportDocument>();

        // The list 'ctrls' contains all the Controls of 'this' form.
        List<Control> ctrls = GetAll(this, typeof(Control)).ToList();

        // Now we add all the components from all the controls which are ReportDocuments to the "reports" list.
        foreach (Control c in ctrls)
            foreach( Component x in get_components(c) )
            {
                if (x is ReportDocument)
                    reports.Add((ReportDocument)x);
            }

        switch (reports.Count)
        {
            case 0:
                MessageBox.Show("No report document found.");
                break;
            case 1:
                Log_On_Database( ((ReportDocument)reports[0]).Database );
                break;
            default:
                MessageBox.Show("Too many report documents found.");
                break;
        } // end switch

    } // end Log_On_Database

如果能在一个 LINQ 语句中完成所有操作就好了。

关于c# - 我可以使用 LINQ 获取某种类型的所有组件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13242762/

相关文章:

vb.net - LINQ 除了使用自定义比较器

c# - Automapper Custom Map 使用 "Include"来获取 child 数

c# - 使属性与 CLR 一起工作的魔力是什么?

c# - 如何在C#中使用FileStream写入文件头

c# - 如何在任务管理器中拥有不同的进程名称(当前进程)名称?

c# - 如何检测一个对象是一个泛型集合,以及它包含哪些类型?

c# - 在 MonoTouch 中的 View Controller (缓存数据)之间传递数据的最佳方式

c# - 使用 Linq 计算列表中枚举值的数量

c# - 是否应该使用 Reflection.Emit 将属性作为方法发出?

c# - 是否有任何已知的 .CompareTo(object value) 方法实际返回小于 -1 或大于 1 的值?