我是 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/