我已经设计了一种技术来处理 rdlc 报告中的多个子报告,但当我试图使其通用且可重复时,我不得不采用该模型并针对每种情况稍微调整它。
例如,如果我定义一个抽象接口,像这样,我只需根据需要将其从 winform 剪切并粘贴到 winform :
abstract class ISolutionStrategy
{
public abstract void AlgorithmInterface(Int64 searchCriteria, SubreportProcessingEventArgs e);
}
首先,我希望能够通过包含一个 has-a 对象将其带入每种形式。我还想封装委托处理分派的行为,并使处理方法也成为“通用”。
那么,设计要求是:
- 创建一个可以包含在winform中的对象来处理多个子报表处理
- 在winform中实例化并配置对象
- 在winform中构建调度表或switch/case语句
- 传入所有方法来处理该 winforms 报表查看器的特定要求
目标是制作一个可以独立测试并坚固耐用的对象,而且不必剪切和粘贴轮子,也不必为每个新的 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;
}
Aside:
在我看来,与
我考虑过的替代方案。我考虑过在报告中使用哈希
名称作为键,函数调用数据作为值。但是,我
真的不知道该怎么做,我认为这会更难
别人来理解。
之后,调用一个函数,重新排列 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;抽象类的声明方式和编译方式似乎有所不同。