SharpShooter Reports.WinRT: parameters

SharpShooter Reports.WinRT parameters

General information

The parameters are the main tool for sending any information from client to a report. Such information usually includes specific settings that affect the report appearance and report generation process. For example, considering the client-server nature of the viewer it is possible to transfer time parameter used in the report from client and specify that server time was used during report generation. Or, for example, the time period used in data selection can be passed through parameters.

Parameters input UI

Report Viewer has the ability to automatically display parameters input UI for general types of parameters.  The main parameter types are as follows:

  • Integer
  • Fractional number
  • Boolean
  • Date
  • String

Besides, there’s possibility to add custom input fields of above listed types, substitute input fields and so on. Thus, for example, we can pass complex object into the report, e.g. Person, which contains fields FirstName and LastName, while our interface just displays two input fields - PersonFirstName and PersonLastName. For more information on customization refer to the corresponding section.

Note: Parameters input UI is displayed only if one or several report parameters don’t have default values and were not configured in the code before the call for report rendering occurs.

In any case it’s always possible to change the parameters with the help of input panel which can be opened by pressing the Parameters button:


The input panel is opened in the upper part of the viewer and has the following look:


Take into consideration that validation of input values for integers is performed and the SetParameters button remains inactive until all fields are filled with correct data. It is also important to note that the fields which don’t have default values are marked with asterisk (*) and are mandatory.

 Validation is performed by default for fields with numeric values, but with the use of mechanisms described in customization section of this guide, it is possible to add custom validation on both server and client side. Error message will be displayed in the same way as the one in embedded validation.

Pay attention to the fact that it is impossible to generate a report until all required parameters are filled, so when a Cancel button is pressed, the parameters are not transferred to the server and the report is not generated.

Configuring parameters in code

Sometimes a user needs to transfer information for the report from the code of a client application. For example, client side time, current culture, etc. Of course it’s possible to motivate a user to input the current time value on client side manually, but obviously, he would be surprised with such a request coming from the application. Moreover, it’s more reasonable to make such parameters hidden from a user. For information on parameters customization refer to the corresponding section.

The other scenario when this seems useful is setting the default values. For example, in case we want the report for previous month to be displayed by default.

The mechanism of configuring parameters in code is quite simple. It is necessary to pass the name of parameter to Parameters property indexer of Report Viewer. For example, we set the current month beginning and end values for DateFrom and DateTo parameters accordingly:

var today = DateTime.Today;
    reportViewer.Parameters["DateFrom"] = today.AddDays(1 - today.Day);
    reportViewer.Parameters["DateTo"] = new DateTime(today.Year, today.Month,
                            DateTime.DaysInMonth(today.Year, today.Month));

Take into consideration that parameters would come into effect only if they are set before the report rendering is initiated.

Customization of parameters handling mechanism

Sometimes there are situations when built-in functions provided by the viewer is not enough and you need to extend current functions.

Main points of extending of the parameters handling mechanism:

  • It is possible to override GetReportParametersInfo service method on the server. It is possible to change parameters list got by the client from server. Typical approach to customization is getting base implementation for forming parameters list of the specified report and then changing, adding or removing parameters that will be visible for the user by changing ReportParametersInfo property values.
  • It is possible to override ValidateParameters service method on the server. This method checks that values were provided to all parameters and that this value corresponds to the parameter type. If you need to make more strict validation you need to implement it in this method.
  • It is possible to override PreprocessParameters method on the server. The method is executed after all parameters are validated. It is necessary to convert parameters got from the user to parameters expected by the report. For example, you can show Name – ID list to the user, and convert ID value to the database object in this method.
  • It is possible to subscribe for the ParametersListReceived viewer event. The event is generated after the list of parameters is got from the server. You can hide parameters and add new ones in this event handler (It’s necessary to note that parameters added on the client in this event won’t be passed to the server.)
  • It is possible to subscribe for the ParametersFilled viewer event. This event is generated after the user has entered report parameters and pressed Set Parameters button. This event occurs to correct and validate parameters.

Let’s consider typical approaches to customization of the events handling:

  1. Validation of parameters on the client side.

It’s quite simple. Subscribe for the event:

reportViewer.ParametersFilled +=reportViewer_ParametersFilled;

In the event handler, extract parameter value from the values collection passed through the event arguments. In case the error is detected it is necessary to add error massage text with the parameter name as a key to the ValidationErrors dictionary.

     

private void reportViewer_ParametersFilled(object sender,
          PerpetuumSoft.WinRT.Viewer.Managing.ParametersFilledEventArgs e)
      {
          var parameter = e.Values.Where(x => x.Name == "param").SingleOrDefault();
          if (parameter != null)
          {
              var value = int.Parse(parameter.Value);
              if (value < 10)
              {
                  e.ValidationErrors.Add("param", "Value cannot be less than 10!");
              }
          }
      }

Since client side validation doesn’t require sending queries to the server it’s strongly recommended to use this type of validation.

  1. Validation of parameters on the server side.

It’s quite simple as well, but the approach differs from the one used on the client side. It is necessary to override ValidateParameters service method and validate parameters in it. The method gets ParameterData list containing parameter description and its value. In case parameter value is not valid it is necessary to remove ParameterData.ParameterInfo.IsValid flag and set error message in the ParameterData.ParameterInfo.ValidationErrorMessage property.

        

protected override void ValidateParameters(List<ParameterData> parametersData)
        {
            base.ValidateParameters(parametersData);
            var parameter = parametersData
                .Where(x => x.ParameterInfo.Name == "parameter")
                .SingleOrDefault();
            if (parameter != null && parameter.Value != null)
            {
                var value = Convert.ToDouble(parameter.Value);
                if (value < 10)
                {
                    parameter.ParameterInfo.IsValid = false;
                    parameter.ParameterInfo.ValidationErrorMessage =
                        "Parameter cannot be less than 10";
                }
                if (value > 20)
                {
                    parameter.ParameterInfo.IsValid = false;
                    parameter.ParameterInfo.ValidationErrorMessage =
                        "Parameter cannot be more than 20";
                }
             }
         }

Pay attention to the fact that it’s recommended using methods represented by the Convert class. The matter is that double type parameter value can be passed as int typed value; it will result in error in case of explicit casting.

  1. Hiding  parameters on the client side

In order to hide a parameter it is necessary to set PromptUser=false property in ParametersListReceived event handler:

      

private void reportViewer_ParametersListReceived(object sender,
          PerpetuumSoft.WinRT.Viewer.Managing.ParametersListReceivedEventArgs e)
      {
          var parameter = e.Parameters
              .Where(x => x.Name == "parameter")
              .SingleOrDefault();
          if (parameter != null)
          {
              parameter.PromptUser = false;
          }
      }

  1. Hiding  parameters on the server side

To hide a parameter on the server side it is necessary to reset ShowOnPanel flag in the overridden GetReportParametersInfo method:

       

public override ReportParametersInfo GetReportParametersInfo(
           string reportName,
           string parameters,
           string parametersType,
           out ExceptionDetailBase reportError)
       {
           var result = base
               .GetReportParametersInfo(reportName,
                   parameters, parametersType, out reportError);
           if (reportError == null)
           {
               var parameter = result.Parameters
                   .Where(x => x.Name == "parameter")
                   .SingleOrDefault();
               if (parameter != null)
               {
                   parameter.ShowOnPanel = false;
               }
           }

  1. Providing parameters list on the client

There are situations when a user needs to select a parameter from the list of provided parameters instead of inputting value manually. It can be done by initializing ValidValues collection in ParametersListReceived event handler on the client side:

       

private void reportViewer_ParametersListReceived(object sender,
           PerpetuumSoft.WinRT.Viewer.Managing.ParametersListReceivedEventArgs e)
       {
           var parameter = e.Parameters
               .Where(x => x.Name == "gender")
               .SingleOrDefault();
           if (parameter != null)
           {
               parameter.ValidValues
                   = new ObservableCollection<ValidValue>()
                   {
                       new ValidValue(){ Label="Male", Value="MALE" },
                       new ValidValue(){ Label="Female", Value="FEMALE" },
                   };
           }
        }

 

  1. Providing parameters list on the server

Parameters list on the server side is filled in the overridden GetReportParametersInfo event. The parameter’s Values collection should be filled in this case:

        

public override ReportParametersInfo GetReportParametersInfo(
            string reportName,
            string parameters,
            string parametersType,
            out ExceptionDetailBase reportError)
        {
            var result = base
                .GetReportParametersInfo(reportName,
                    parameters, parametersType, out reportError);
            if (result != null)
            {
                var parameter = result.Parameters
                    .Where(x => x.Name == "string")
                    .SingleOrDefault();
                if (parameter != null)
                {
                    parameter.Values.Add(new LabeledValue()
                    {
                        Label = "Male",
                        Value = "MALE"
                    });
                    parameter.Values.Add(new LabeledValue()
                    {
                        Label = "Female",
                        Value = "FEMALE"
                    });
                }
            }
}

  1. Adding parameters on the client

It is possible to add a client side parameter in the ParametersListReceived event handler. Remember that additional parameters created in this event on the client side will not be passed to the server. In case a user needs to create a parameter that will be handled on the server side, the parameter should be created on the server side accordingly.  The ParametersFilled event can be used for handling a parameter created on the client side.

    

private void reportViewer_ParametersListReceived(object sender,
        PerpetuumSoft.WinRT.Viewer.Managing.ParametersListReceivedEventArgs e)
    {
        e.Parameters.Add(new PerpetuumSoft.WinRT.Viewer.Model.ReportParameter()
            {
                Name = "ClientSideParameter",
                Prompt = "My Parameter",
                PromptUser = true,
                Type = PerpetuumSoft.WinRT.Viewer.Model.ParameterTypeEnum.String,
                Visibility = true,                   
            });
    }

  1. Adding parameters on the server

To add a server side parameter, it is required to override GetReportParametersInfo method and add a new parameter to the collection formed by the basic method implementation:

        

public override ReportParametersInfo GetReportParametersInfo(
            string reportName,
            string parameters,
            string parametersType,
            out ExceptionDetailBase reportError)
        {
            var result = base
                .GetReportParametersInfo(reportName,
                     parameters, parametersType, out reportError); 
            if (result != null)
            {
                result.Parameters.Add(new ParameterInfo()
                {
                    DisplayName = "My Parameter",
                    Name = "ServerSideParameter",
                    OriginalType = "System.String",
                    ShowOnPanel = true,
                    Type = ParameterType.String,
                })
            }
 
         }
 
  1. Handling of unprocessable parameters

As it was mentioned earlier, a viewer is able to automatically display input fields for a limited number of parameter types. In case a user has to deal with parameters which don’t correspond to the supported types, then the list of such parameters will be passed to OnUnprocessableParametersDetected method. Thus, overriding this method will make it possible to handle such parameters. In the following example we will use two parameters for input of the first and last name for User parameter and, then create a User object in PreprocessParameters method using the entered first and last name values.

       

protected override void OnUnprocessableParametersDetected(
           List<PerpetuumSoft.Reporting.DOM.Parameter> problemParameters,
           List<ParameterInfo> resultList)
       {
           var user = problemParameters.Where(x => x.Name == "User")
               .SingleOrDefault();
           if (user != null)
           {
               resultList.Add(new ParameterInfo()
                   {
                       DisplayName = "User First Name",
                       Name = "UserFirstName",
                       OriginalType = "System.String",
                       ShowOnPanel = true,
                       Type = ParameterType.String                       
                   });
               resultList.Add(new ParameterInfo()
               {
                   DisplayName = "User Last Name",
                   Name = "UserLastName",
                   OriginalType = "System.String",
                   ShowOnPanel = true,
                   Type = ParameterType.String
               });
           }
       }
       protected override void PreprocessParameters(
           IDictionary<string, object> parameters, ReportParametersInfo parameterInfo)
       {
           base.PreprocessParameters(parameters, parameterInfo);
           if (parameters.ContainsKey("UserFirstName")
               && parameters.ContainsKey("UserLastName"))
           {
               parameters.Add("User",
                   new User(
                       Convert.ToString(parameters["UserFirstName"]),
                       Convert.ToString(parameters["UserLastName"])));
           }
       }

 

Add Feedback