I'm showing a remote report in a ReportViewer
control. The report loads with a few default parameters. So far everything is ok.
But when i change a few input values and hit View Report
then the report simply shows the data with the default values. The parameters that i changed in the input fields are also reset.
All the code i have is this:
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana"
Font-Size="8pt" Height="642px" ProcessingMode="Remote" Width="100%">
<ServerReport ReportPath="http://server.com/Product/Dashboards/test.rdl"
ReportServerUrl="http://server.com/ReportServer" />
</rsweb:ReportViewer>
The CodeBehind is basically empty. All it has now is an empty Page_Load
.
That is all my code.
But it feels like a ViewState issue? But I am not sure where to look.
Anyone any idea why the parameters are resrt when I press on the View Report
button?
I solved this by setting the parameters myself in the Code Behind. So when the report is submitted, i then get all the entered data, put that in a ReportParameters
collection.
But unfortunately this wasn't as easy and straight forward as one would think. At first you might think this is stored in: YourReport.ServerReport.GetParameters()
. But that is not the case!
To get the submitted values from your report you can use the following code:
public ReportParameter[] GetCurrentParameters(Microsoft.Reporting.WebForms.ReportViewer viewer)
{
Control params1Area = FindParametersArea(viewer);
List<ReportParameter> params1 = new List<ReportParameter>();
FindParameters(params1Area, params1);
return params1.ToArray();
}
private Control FindParametersArea(Microsoft.Reporting.WebForms.ReportViewer viewer)
{
foreach (Control child in viewer.Controls)
{
if (child.GetType().Name == "ParametersArea")
return child;
}
return null;
}
private void FindParameters(Control parent, List<ReportParameter> params1)
{
Type _ParameterControlType = System.Reflection.Assembly.GetAssembly(typeof(Microsoft.Reporting.WebForms.ReportViewer)).GetType("Microsoft.Reporting.WebForms.BaseParameterInputControl");
ReportParameter param;
Microsoft.Reporting.WebForms.ReportParameterInfo paramInfo;
String[] paramValues;
foreach (Control child in parent.Controls)
{
if (_ParameterControlType.IsAssignableFrom(child.GetType()))
{
paramInfo = (Microsoft.Reporting.WebForms.ReportParameterInfo)GetPropertyValue(child, "ReportParameter");
if (paramInfo == null)
continue;
paramValues = (string[])GetPropertyValue(child, "CurrentValue");
if (paramValues != null && paramValues.Length > 0)
{
param = new ReportParameter();
param.Name = paramInfo.Name;
param.Values.AddRange(paramValues);
params1.Add(param);
}
}
FindParameters(child, params1);
}
}
public object GetPropertyValue(object target, string propertyName)
{
return target.GetType().GetProperty(propertyName, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public).GetValue(target, null);
}
Source: http://forums.asp.net/t/1057747.aspx/1 (Also Visual Basic examples)
You invoke those methods by just using the following line of code. Preferably in a if(IsPostBack)
scope within your Page_Load
for example.
ReportParameter[] reportParameters = GetCurrentParameters(ReportViewer1);
It is then possible to overwrite the submitted values if you also have custom textfields. You can easily do that like so:
reportParameters[4] = new ReportParameter("year", "2013", true);
You obviously have to know what param is stored at index 4
. But you could also make an easy lookup function that searches for the reportParameter
with a specific name. So in my case year
.
protected void ChangeParameterValue(String name, String newValue, ref ReportParameter[] parameters)
{
foreach (ReportParameter param in parameters)
{
if (String.Equals(param.Name, name))
{
param.Values[0] = newValue;
break;
}
}
}
You use that like so:
ChangeParameterValue("year", "2013", ref reportParameters);
This way you don't have to worry about at what index
a certain parameter is placed.