Reputation: 12293
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
Upvotes: 0
Views: 2638
Reputation: 12293
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));
}
}
Upvotes: 1
Reputation: 2815
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?
Upvotes: 0