How to use a base class with abstract methods to handle delegate calls?

Here is the base class:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.Reporting.WinForms; abstract class ReportWinForm : System.Windows.Forms.Form { // This will be the one line of code needed in each WinForm--providing the base class a reference // to the report, so it has access to the SubreportProcessing event protected ReportViewer WinFormReportViewer { get; set; } // Making this abstract requires each derived WinForm to implement GetReportData--foolproof! protected abstract DataResult GetReportData(SubreportProcessingEventArgs e); // Wire up the subreport_processing handler when any WinForm loads // You could override this in derived WinForms classes if you need different behavior for some WinForms, // but I would bet this default behavior will serve well in most or all cases protected virtual void Form1_Load(object sender, EventArgs e) { WinFormReportViewer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing); } // When the Subreport processing event fires, handle it here // You could also override this method in a derived class if need be protected virtual void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e) { // Get the data needed for the subreport DataResult dataResult = this.GetReportData(e); e.DataSources.Clear(); e.DataSources.Add(new ReportDataSource(dataResult.Label, dataResult.Table)); } } 

Here is a specific implementation:

 public frmTestAllView() { //base.WinFormReportViewer = reportViewer1; //Hook-up callbacks to the base class ReportWinForm InitializeComponent(); } private void frmTestAllView_Load(object sender, EventArgs e) { // TODO: This line of code loads data into the 'AFC_ObsolescenceDataSet.up_Fill_frmInternalCaseStatus_All' table. You can move, or remove it, as needed. this.up_Fill_frmInternalCaseStatus_AllTableAdapter.Fill(this.AFC_ObsolescenceDataSet.up_Fill_frmInternalCaseStatus_All); this.reportViewer1.RefreshReport(); } // The search parameters will be different for every winform, and will presumably // come from some winform UI elements on that form, eg, parentPartTextBox.Text protected override DataResult GetReportData(SubreportProcessingEventArgs e) { // Return the data result, which contains a data table and a label which will be // passed to the report data source // You could use DataSet in DataResult instead of DataTable if needed switch (e.ReportPath) { case "rptSubAlternateParts": return new DataResult( new BLL.AlternatePartBLL().GetAlternativePart(parentPartTextBox.Text) , "BLL_AlternatePartBLL" ); case "rptSubGetAssemblies": return new DataResult( new BLL.SubAssemblyBLL().GetSubAssemblies(someOtherTextBox.Text) , "BLL_SubAssemblyBLL" ); default: throw new NotImplementedException(string.Format("Subreport {0} is not implemented", e.ReportPath)); } } 

There are two problems:

  • DataResult not recognized by Visual Studio 2008, even if it is in the ReportWinForm base class.
  • The designer in VS 2008 claims that the class derived from ReportWinForm cannot be edited, although the base class comes from Form .

For more details, see How can a delegate respond to multiple events using a generic and extensible class?

+1
source share
1 answer

DataResult is not recognized by Visual Studio 2008, even if it is in the ReportWinForm base class.

If it is valid in the class, outside the class you must specify ReportWinForm.DataResult .

The designer in VS 2008 claims that the class derived from ReportWinForm cannot be edited, although the base class comes down from the form.

Are you sure that all DLL dependencies are correct? You need all the DLLs that define all the base classes.

By the way, you can download the Visual Studio 2012 Express version for free if you can and want to upgrade. Sub>

+1
source

All Articles