Integrating Infragistics Reporting in Visual Studio LightSwitch Applications

[Infragistics] Mihail Mateev / Monday, November 28, 2011

Developers could enjoy the Infragistics Reporting In NetAdvantage Vol.2011.2.  With this product you could cerate modern, innovative reports in Visual Studio. Infragistics Reporting is designed manly to create easy reports in XAML products (Silverlight and WPF applications) – without code and/or programmatically. It is a very common case to integrate Infragistics Reporting in other  platforms: ASP.Net, Windows Forms, Visual Studio LightSwitch. This article is about how to integrate Infragistics reports in Visual Studio LightSwitch applications.

If you have no experience with Visual Studio LightSwitch it is recommended to look at Visual Studio LightSwitch Team Blog , LightSwitch Developer Center and Visual Studio LightSwitch Help Website.

More information about how to create Visual Studio LightSwitch application you could also find in the book Microsoft Visual Studio LightSwitch Business Application Development.

 

Approaches to integrate Infragistics Reporting

There are several possible ways to integrate Infragistics Reporting in LightSwitch applications:

  • Using custom control libraries
  • Creating custom control extensions
  • Creating custom screen templates with mentioned above custom controls or control extensions

 

In this post will be demonstrated the easiest approach: using custom control libraries. More information how to use custom controls in Visual Studio LightSwitch you could learn in the article Creating a Visual Studio LightSwitch Custom Silverlight Control

 

Data Sources

Both products Infragistics Reporting and Visual Studio LightSwitch support different data sources.

LigthSwitch applications could use Databases(SQL Server, MySQL, Oracle tec.),  SharePoint Lists and WCF RIA Services. Infragistics reports support databases, WCF RIA Services and Object data sources (collections).

This article shows an example using as a data source WCF RIA Services for both: LightSwitch data and report data source.

Additional information how to use Visual Studio LightSwitch Applications with WCF RIA Services you could find in this article. Details about how to work With RIA Services in Silverlight Using client-Side rendering you could find here.

 

Report wrapper

In the sample application is used custom control library to wrap report and report viewer. NetAdvantage Reporting supports both server-side and client-side rendering. When you are planning to integrate Infragistics reports in LightSwitch applications the right solution is to use client-side rendering. Report viewer has a complex property RenderSettings. In this property when set DefinitionUri property to let XamReportViewer to know which reporting service should use.

When we are using a server-side rendering :

<ig:ServerRenderSettings DefinitionUri="ReportLibrary;component/MyReport.igr" ServiceEndpointUri="/ReportService.svc" />

For client-side rendering:

<ig:ClientRenderSettings DefinitionUri="ReportLibrary;component/MyReport.igr" />

LightSwitch client is a pure Silverlight application and it is not possible to refer non Silverlight libraries. This is the reason to use here Silverlight WCF RIA Services Class Library project with a report definition in the Silverlight client part. Report viewer will use a client-side rendering. WEB project will contain ADO.NET Entity Framework classes and Domain Service Class instance.

More information how to implement client-side rendering you can find here.

How to use custom controls in Visual Studio LightSwitch you could learn in the article Creating a Visual Studio LightSwitch Custom Silverlight Control

 

Implementation

Requirements:

 

Create a Silverlight WCF RIA Services Class Library project. Add ADO.Net Entity Framework and Domain Service Class instances. Let’s Entity Framework use the Northwind sample database.

To be possible to use this data from LightSwitch you should add two things.

  • Add an attribute [Query(IsDefault = true)]  for one query for each entity in Domain Service Class.
  • Add a [Key] attribute for primary key fields in metadata file, created  when you add Domain Service Class instance.

 

Add an attribute [Query(IsDefault = true)]  for each entity in NwDomainService.cs

 

 

   1: [Query(IsDefault = true)]
   2: public IQueryable<Customer> GetCustomers()
   3: {
   4:     return this.ObjectContext.Customers;
   5: }

 

In this sample is used entity Customers, generated from Northwind sample database. Let’s add a method GetCustomersbyCountry(string country) returns customers filtered by country.

   1: public IQueryable<Customer> GetCustomersbyCountry(string country)
   2:         {
   3:             if (null == country || country.Equals(string.Empty))
   4:             {
   5:                 return GetCustomers();
   6:             }
   7:  
   8:             return GetCustomers().Where(c => c.Country == country);
   9:         }

 

Add a [Key] attribute for primary key fields in NwDomainService.metadata.cs

   1: internal sealed class CustomerMetadata
   2:  {
   3:  
   4:      // Metadata classes are not meant to be instantiated.
   5:      private CustomerMetadata()
   6:      {
   7:      }
   8:  
   9:      public string Address { get; set; }
  10:  
  11:      public string City { get; set; }
  12:  
  13:      public string CompanyName { get; set; }
  14:  
  15:      public string ContactName { get; set; }
  16:  
  17:      public string ContactTitle { get; set; }
  18:  
  19:      public string Country { get; set; }
  20:  
  21:      [Key]
  22:      public string CustomerID { get; set; }
  23:  
  24:      public string Fax { get; set; }
  25:  
  26:      public string Phone { get; set; }
  27:  
  28:      public string PostalCode { get; set; }
  29:  
  30:      public string Region { get; set; }
  31:  }
  32:     }

 

Report

Add a report using Customer entity and style it. Do care about report parameters.

 

Report Viewer

Let’s  use in the client application method GetCustomersbyCountry in the instance of the class DomainDataSource, which is used with WCF RIA Services. TextBox will be used to visualized parameter for your query.

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <Grid.RowDefinitions>
   3:         <RowDefinition Height="50" />
   4:         <RowDefinition />
   5:     </Grid.RowDefinitions>
   6:  
   7:     <riaControls:DomainDataSource x:Name="domainDataSource" LoadedData="DomainDataSourceLoadedData"
   8:                                   AutoLoad="False" 
   9:                                   QueryName="GetCustomersbyCountryQuery">
  10:  
  11:         <riaControls:DomainDataSource.DomainContext>
  12:             <Web:NwDomainContext />
  13:         </riaControls:DomainDataSource.DomainContext>
  14:         <riaControls:DomainDataSource.QueryParameters>
  15:             <riaControls:Parameter ParameterName="country" Value="{Binding ElementName=countryTextBox, Path=Text}" />
  16:         </riaControls:DomainDataSource.QueryParameters>
  17:     </riaControls:DomainDataSource>
  18:  
  19:     <StackPanel Height="40" HorizontalAlignment="Left" Orientation="Horizontal" VerticalAlignment="Top">
  20:         <sdk:Label Content="Select Country:" Margin="5" VerticalAlignment="Center" FontSize="12" FontWeight="Bold" />
  21:         <TextBox Name="countryTextBox" Width="100" Margin="5" Text="{Binding ElementName=IgReportingPage, Path=Country}" TextChanged="CountryTextBoxTextChanged" />
  22:         <Button Command="{Binding Path=LoadCommand, ElementName=domainDataSource}" Content="Load" Margin="5"  Width="100"  Style="{StaticResource LoadButton}" Name="customerDomainDataSourceLoadButton" />
  23:     </StackPanel>
  24:  
  25:     
  26:     <ig:XamReportViewer Grid.Row="1"  Margin="20" Name="xamReportViewer1">
  27:         <ig:XamReportViewer.RenderSettings>
  28:             <ig:ClientRenderSettings DefinitionUri="/IgReportingLibrary;component/NwReport.igr">
  29:                 <ig:ClientRenderSettings.DataSources>
  30:                     <!-- Overrides Order_Detail data source defined at design time-->
  31:                     <ig:DataSource TargetDataSource="Customer" ItemsSource="{Binding ElementName=domainDataSource}" />
  32:                 </ig:ClientRenderSettings.DataSources>
  33:             </ig:ClientRenderSettings>
  34:         </ig:XamReportViewer.RenderSettings>
  35:     </ig:XamReportViewer>
  36: </Grid>

 

Report Wrapper

Add a dependency property named Country. You will use it to receive required parameter from LightSwitch.

   1: #region public string Country
   2: /// <summary>
   3: /// 
   4: /// </summary>
   5: public string Country
   6: {
   7:     get { return GetValue(CountryProperty) as string; }
   8:     set { SetValue(CountryProperty, value); }
   9: }
  10:  
  11: /// <summary>
  12: /// Identifies the Country dependency property.
  13: /// </summary>
  14: public static readonly DependencyProperty CountryProperty =
  15:     DependencyProperty.Register(
  16:         "Country",
  17:         typeof(string),
  18:         typeof(ReportingControl),
  19:         new PropertyMetadata(null, OnCountryPropertyChanged));
  20:  
  21: /// <summary>
  22: /// CountryProperty property changed handler.
  23: /// </summary>
  24: /// <param name="d">ReportingControl that changed its Country.</param>
  25: /// <param name="e">Event arguments.</param>
  26: private static void OnCountryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  27: {
  28:     ReportingControl source = d as ReportingControl;
  29:     var value = e.NewValue as string;
  30:     var oldVvalue = e.OldValue as string;
  31:     if (source != null && value != oldVvalue)
  32:     {
  33:         source.domainDataSource.Load();
  34:     }
  35:  
  36: }
  37: #endregion public string Country

Load data in the DomainDataSource instance programmatically when TextBox content has changed.

 

 

 

   1: #region CountryTextBoxTextChanged
   2: private void CountryTextBoxTextChanged(object sender, TextChangedEventArgs e)
   3: {
   4:     domainDataSource.Clear();
   5:  
   6:     domainDataSource.QueryName = "GetCustomersbyCountryQuery";
   7:  
   8:     domainDataSource.QueryParameters.Clear();
   9:     domainDataSource.QueryParameters.Add(new Parameter { ParameterName = "country", Value = countryTextBox.Text });
  10:  
  11:     domainDataSource.Load();
  12:  
  13: }
  14: #endregion //CountryTextBoxTextChanged

 

In the DomainDataSource instance attach to the event LoadedData a new event handler, named DomainDataSourceLoadedData. In this method call method RenderReport() of the event viewer. This method will update your viewer with the actual data.

   1: #region DomainDataSourceLoadedData
   2:  private void DomainDataSourceLoadedData(object sender, LoadedDataEventArgs e)
   3:  {
   4:      xamReportViewer1.RenderReport();
   5:  }
   6:  #endregion //DomainDataSourceLoadedData

 

Create a second UserControl instance in the project,  named LightSwitchReportingControl. Include the first control with the report viewer inside it. Bind the Country property to a specific data source from LightSwitch screen:

Country="{Binding Screen.Customercountry}"

Customercountry will be a parameter, used when make queries from the LightSwitch application using WCF RIA Services.

 

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <loc:ReportingControl  Margin="0" x:Name="reportingControl1" Country="{Binding Screen.Customercountry}" />
   3: </Grid>

 

Repeat the same operation with another custom control, named LightSwitchReportingDetailControl. In this control in the binding use

Screen.GetCustomersbyCountry.SelectedItem.Country

 

This will be the selected item in the LightSwitch list detail screen.

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <loc:ReportingControl  Margin="0" x:Name="reportingControl1" Country="{Binding Screen.GetCustomersbyCountry.SelectedItem.Country}" />
   3: </Grid>

 

Visual Studio LightSwitch Application

Add a LightSwitch application to the solution and use as a data source WCF RIA Services from our library.

Create a search screen using GetCustomersbyCountry query.  Parameter appears as a data item (Customercountry in this case). Add new custom control (select from the custom library LightSwitchReportingControl (user control, designed to use data from Customercountry data source).

Create another screen using List and Details Screen template. Add a custom control, predicted to use a Country property from the selected item ( LightSwitchReportingDetailControl in this case).

Run the application. In the filter field type “Spain” You will receive all customers from Spain. Report viewer will offer a report only with customers from Spain. 

Select list detail screen and select one of the customers. In the report viewer you will see a report only with customers from the country as a country of the selected item.

Now you know how to integrate Infragistics Reporting in LightSwitch applications using custom control libraries.

Source code you could download here:

 Follow news from Infragistics in https://www.infragistics.com and twitter: @infragistics for more information about new Infragistics Reporting. Expect more posts in https://www.infragistics.com/community/blogs about how to use reports in custom control extensions for Visual Studio LightSwitch.