views:

415

answers:

2

Hi !

I'm working with MS Reporting Services. The underlying datasource is

IEnumerable<MyObject>, I'm not using DataSets.

Every MyObject has properties and some other IEnumerable collections. In the report I want to display all the properties from MyObject and the collections lists too. I didn't know how to display this inner collections, so I've made a SubReport to which I passed the MyObject.Id so that the SubReport could retrieve the object by himself and Build a the DataSource for these inner collections. I do this in this event.

myReportViewer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);

private void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
{
    int id;
    if (e.Parameters.Count > 0 && int.TryParse(e.Parameters[0].Values[0], out id))
    {
     MyObject current = myObjects.Where(x => x.MyObject.Id == id).FirstOrDefault();

     InnerListBindingSource.DataSource = current.InnerCollection;
     e.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource(
      "MyInnerCollectionDataSource", InnerListBindingSource));
    }
}

But there is always "The SubReport could not be shown" in my Master Report. (Master report - subreport are correctly binded)

Any Idea why? Or how to resolve this in a more elegant way ?

Thank you

A: 

If I understand you correctly, you have a structure that resembles a table. So why don't you take a DataTable? ReportingServices offers easy access to those. Or did I get you wrong there?

StampedeXV
This Collection is retrieved from ObjectRelational Mapper, and it contains ForeignKey objects, Foreign Collections etc. I'd have to rebuild it do the DataTable.. Do you think that's a good approach?
PaN1C_Showt1Me
Honestly: I don't know. But a DataSet/DataTable is usually a good choice to map to from a relational data source. DataSet offers most functionality a DataBase does, and a table is the basic structure of a relational datasource. I only worked with a Table until now, so I guess that could also be the reason why I'd choose them again. :)
StampedeXV
I guess it depends how hard it is to retrieve a DataTable in comparison to fixing your problem.
StampedeXV
+1  A: 

OK.

So I went to this solution and it's working:

private IEnumerable<MyObject> myObjects;

public ReportViewerForm(IEnumerable<MyObject> myObjects)
{
    InitializeComponent();

    this.myObjects = myObjects;
    this.WindowState = FormWindowState.Maximized;

    ReportViewer reportViewer = new ReportViewer();            

    reportViewer.ProcessingMode = ProcessingMode.Local;

    reportViewer.LocalReport.ReportEmbeddedResource = @"SomePath." + "Report1.rdlc";
    /*reportViewer.LocalReport.ReportPath = @"SomePath\Report1.rdlc"; */

    reportViewer.LocalReport.SubreportProcessing +=
       new SubreportProcessingEventHandler(SubreportProcessingEventHandler);            

    reportViewer.LocalReport.DataSources.Add(
       new ReportDataSource("MyDataSource", myObjects));

    reportViewer.LocalReport.SetParameters(new List<ReportParameter> 
    {
     new ReportParameter("param1", ..WhatEver..),
     ...
    }); 

    reportViewer.Dock = DockStyle.Fill;
    this.panel1.Controls.Add(reportViewer);

    reportViewer.RefreshReport();
}

void SubreportProcessingEventHandler(object sender, SubreportProcessingEventArgs e)
{          
    /* For example ID parsing.. when you have it defined in .rdlc file.. */
    int id;
    if (e.Parameters.Count > 0 && int.TryParse(e.Parameters[0].Values[0], out id))
    { 
     MyObject current = myObjects.Where(x => x.MyObject.Id == id).FirstOrDefault();

     e.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource(
      "InnerListDataSource", current.InnerList));              
    }           
}
PaN1C_Showt1Me