1

基本クラスは次のとおりです。

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));
    }
}

具体的な実装は次のとおりです。

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, e.g., 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));

    }
}

2 つの問題があります。

  1. DataResultReportWinForm 基本クラスにあっても、Visual Studio 2008 では認識されません。
  2. VS 2008 のデザイナーは、基本クラスが の子孫であっても、ReportWinForm から派生したクラスは編集できないと主張していますForm

詳細については、ジェネリックで拡張可能なクラスを使用してデリゲートが複数のイベントに応答する方法を参照してください。

4

1 に答える 1

1

DataResult は、ReportWinForm 基本クラスにありますが、Visual Studio 2008 では認識されません。

それが本当にクラス内にある場合は、クラス外に指定する必要がありますReportWinForm.DataResult

VS 2008 のデザイナーは、基本クラスが Form の子孫であっても、ReportWinForm から派生したクラスは編集できないと主張しています。

すべての DLL 依存関係が正しいと確信していますか? すべての基本クラスが定義されているすべての DLL が必要です。

ちなみに、Visual Studio 2012 Express エディションは無料でダウンロードできます。

于 2013-02-14T18:25:52.083 に答える