I'm trying to use the ReportViewer control (in remote mode) in a winform app. Everything works great until I try and change the ReportPath of the control (in response to a TreevIew after select event ) when the currently visible report is a report that has been drilled into from the original report specified in ReportPath e.g.
ReportViewer rv = new ReportViewer();
/* other code */
rv.ServerReport.ReportPath = "/Report1";
rv.RefreshReport();
User then clicks on a link in Report 1 that jumps to Report 2 (still within the same control).
Now if you try and set the ReportPath to anything you get an "Operation is not valid due to the current state of the object" being thrown by the internal set_ReportPath method. As long as the ReportViewer control is showing Report1 all is well (for example if the user drilled down and them navigated back to the top level report). Is there something I should be doing differently The only way round this at the moment is to create a new ReportViewer control everytime a different node is selected in the treeview which seems wrong as all I want to do is change the report path and parameters for the existing control.

Error "Operation is not valid due to the current state of the object"
Kento
JDiego
Thanks Brian, that worked perfectly
davidbellot
Here is the hacky way I worked around this shortcoming. If setting the report path fails I call PerformBack() and then try setting the report path again. If I'm 5 levels deep this still works. I will rip this code out as soon as .Reset() is availiable.
bool l_bRetry = true;
while (l_bRetry)
{
try
{
m_viewer.ServerReport.ReportPath = m_reports.SelectedItem.Value;
l_bRetry = false;
}
catch
{
m_viewer.PerformBack();
}
}
AnaC
johanm
We were using the following code to get back to the parent report in the web application.
But if we keep the session idle for more than 6 min(if we do with in that time period it works perfectly), SSRSReportViewer.PerformBack(); will throw an error
"This operation can only be performed on drillthrough report".
protected void btnBack_Click(object sender, EventArgs e)
{
GetParentReport();
SSRSReportViewer.ServerReport.ReportPath = "/" + ReportFolder + "/" + this.ReportName.ToString();
SSRSReportViewer.ServerReport.Refresh();
}
private void GetParentReport()
{
if (SSRSReportViewer.ServerReport.IsDrillthroughReport)
{
SSRSReportViewer.PerformBack();
GetParentReport();
}
}
Julian Keith Loren MCSD MCAD
That approach will work. You could also swap out instances of the report viewer on the form, though it will require you to set property values on the viewer control again:
ControlCollection coll = oldViewer.Parent.Controls;
int oldIndex = coll.IndexOf(oldViewer);
ReportViewer newViewer = new ReportViewer();
coll.AddAt(oldIndex, newViewer);
coll.Remove(oldViewer);
Aleks Spacca
Christian38
ahives
For the webform control there doesn't seem to be a Reset method but what I have done is just called the PerformBack method recursively to get back to the top level before modifying the report path. Is that the correct approach e.g.
private void GetBack()
{
if (rv.ServerReport.IsDrillthroughReport)
{
rv.PerformBack();
GetBack();
}
}
private void ShowReport(String instance)
{
GetBack();
rv.ServerReport.ReportPath = RPT_INSTANCE_SUMMARY;
ReportParameter rp = new ReportParameter("instance", instance, false);
rv.ServerReport.SetParameters(new ReportParameter[] { rp });
}
Trevor Damster
Rulery
mPaskov
A more elegant way to do that is:
while (m_reportViewer.ServerReport.IsDrillthroughReport)
m_reportViewer.PerformBack();
bill_chapin
Any update on when this method will be added to the web version of the Report Control
The hack works OK, but as Thambu states, the PerformBack method will throw an exception ("This operation can only be performed on a drillthrough report" - even when it is a drillthrow report and the IsDrillthroughReport property is true), if the page is idle for a couple of minutes...
Natuk