我已经设置了一种技术来处理 rdlc 报告中的多个子报告,但是由于我试图使其通用且可重复,因此我不得不采用该模型并针对每种情况对其进行微调。
例如,如果我定义一个抽象接口,就像这样,我只是根据需要将它从 winform 剪切并粘贴到 winform:
abstract class ISolutionStrategy
{
public abstract void AlgorithmInterface(Int64 searchCriteria, SubreportProcessingEventArgs e);
}
首先,我希望能够通过包含一个 has-a 对象将其带入每种形式。我还想封装委托处理调度的行为,并使处理方法也“通用”。
所以,设计要求是:
- 创建一个可以包含在winform中的对象来处理多个子报表处理
- 在winform中实例化和配置对象
- 在 winform 中构建调度表或 switch/case 语句
- 传入所有方法来处理该 winform 的报表查看器的特定要求
目标是制作一个可以独立测试并变得健壮的对象,并且不必剪切和粘贴轮子并为每个新的 Winform 进行大量手动调整。
在我看来,有人找到了比我目前拥有的更好的设计。
创建一个可以包含在winform中的对象来处理多个子报表处理
到目前为止,我在本地表单加载事件中有一个委托:
this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
这由 *LocalReport_SubreportProcessing* 方法中的 switch 语句处理。
该方法的主体包含一个 switch 语句:
void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
{
String commonSubreportKey = _commonSubreportKey;
switch (e.ReportPath)
{
case "rptSubAlternateParts":
runSubAlternatePart(e, commonSubreportKey, new GetAlternateParts());
break;
case "rptSubGetAssemblies":
runSubFailurePart(e, commonSubreportKey, new GetAssemblies());
break;
case "rptSubGetAssemblies":
runSubGetGetEndItemLRMFailureInfo(e, commonSubreportKey, new GetEndItemLRMFailureInfo());
break;
case "rptSubGetAssemblies":
runSubGetSubAssemblies(e, commonSubreportKey, new GetSubAssemblies());
break;
default:
break;
}
在旁边:在我看来,与我考虑的替代方案相比,这个开关主要是人类可读的。我考虑使用以报表名称作为键、函数调用数据作为值的散列。但是,我真的不知道该怎么做,我认为其他人会更难理解。
之后,调用一个函数,重新排列从 switch 语句中的函数调用传递的信息:
private static void runSubAlternatePart(SubreportProcessingEventArgs e1, String commonReportKey, GetAlternatePart myAP)
{
myAP.AlgorithmInterface(commonReportKey, e1);
}
这种重新排列绝对是代码口吃,但似乎是我试图实现的策略模式的必要中间体:
abstract class IStrategy
{
public abstract void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e);
}
以下是其中一份报告的战略的具体实施:
class GetAlternatePart : IStrategy
{
private BLL.AlternatePartBLL ds = new BLL.AlternatePartBLL();
public override void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e)
{
e.DataSources.Clear();
DataTable myDataTable = ds.GetAlternativePart(searchParam);
DataSet myDataSet = new DataSet();
myDataSet.Tables.Add(myDataTable);
e.DataSources.Add(new ReportDataSource("BLL_AlternatePartBLL", myDataSet.Tables[0]));
}
}
}
无论如何,我的愿望是不必在报告之间重复使用相同的逻辑,因为我有许多带有多个子报告的报告。
我想要一种使用类来动态创建发生口吃的中间部分的库质量方式,并且我想传入一个“匿名”函数,它实际上实现了子报表与其相应数据源的详细连接。
对于带有子报表的单个报表,甚至是几个一次性报表,我所做的是可以的,但如何才能减少手动、更健壮和更可测试呢?
我的环境是 Visual Studio 2008,目标是 .NET 3.5;抽象类的声明方式和编译方式似乎有所不同。