Telerik blogs

With the release of WCF RIA Services, Microsoft has made it much easier to implement multi-tier Silverlight based applications. Data resides in a database on the server and is accessible through the use of an ORM such as Entity Framework or OpenAccess. WCF RIA Services takes care of moving this data between the server and the client application by using Domain Services in conjunction with the ORM. As you may already know, Telerik Reporting includes a WCF based service responsible for rendering and serving up reports. This service however, is not based on WCF RIA Services, so a few steps must be taken in order to get the two working together. In this article, I’ll be showing you the necessary steps you need to take in order to get Telerik Reporting working within a WCF RIA Services based Silverlight application.

The Application

The application we will be creating actually looks pretty simple up front, but a lot will be going on behind the scenes. It will essentially display a list of Product Subcategories from the AdventureWorks database in a DataGrid. Each row in the DataGrid will contain a button that can be clicked to generate a report about which products are in that category.

RIA Services Reporting Application

You should be able to follow along with this article to create a working application. Please note that your environment will need to meet the following requirements before you can successfully create the application.

Creating the Application

In this series of steps, we will create the initial application. This application will be based on the Silverlight Business Application template. This template provides us with a basic navigation application and support for RIA Services.

  • Select File -> New -> Project
  • Locate and select the template for a Silverlight Business Application.
  • Set the name of the application to be ReportingDemo.
  • Click OK.

Creating the Entity Data Model

In the following steps we will create an ADO.NET Entity Data Model. This model will allow us to access data from a relational database quickly and easily through code. We will be able to use this model as the basis for a Domain Service we create in a future step.

  • Right click on the ReportingDemo.Web project and select Add -> New Item...
  • Locate and select the template for an ADO.NET Entity Data Model.
  • Set the name of the model to be AdventureWorksModel.edmx and click Add.
  • Select Generate from database and click Next.
  • Choose the AdventureWorks database as the data connection and click Next.
  • In the treeview, expand tables and select to add the Product and ProductSubcategory tables to the model.
  • Make sure Pluralize or singularize generated object names is checked.
  • Click Finish.
  • Build the project.

Extending the Model

In this section, we will extend the functionality of the AdventureWorksEntities ADO.NET Entity Data Model. We will be adding a custom query that returns products of a specific SubcategoryID.

  • Right click on the ReportingDemo.Web project and select Add -> Class...
  • Set the name the class to AdventureWorksModelExt.cs.
  • Paste the following partial class into the source file, overwriting the AdventureWorksModelExt class.
    public partial class AdventureWorksEntities
    {
        public System.Collections.Generic.List<Product> GetProductsBySubcategory(int subcategoryId)
        {
            return this.Products.Where(p => p.ProductSubcategoryID == subcategoryId).ToList();
        }
    }
  • Build the project.

Adding the Domain Service

This is where we will begin getting into WCF RIA Services. The next bit of code we generate is what's responsible for establishing communication between the Silverlight and ASP.NET applications. The Domain Service, as it's called, is responsible for controlling how the application accesses and uses our Entity Framework based model.

  • Right click on the ReportingDemo.Web project and select Add -> New Item...
  • Locate and select the template for a Domain Service Class.
  • Set the name of the domain service to AWDomainService.cs and click Add.
  • In the displayed dialog, select AdventureWorksEntities (Entity Framework) from the drop down.
  • Check all check boxes for each entity. Make sure to check the “Generate associated classes for metadata” check box as well.
  • Click OK.
  • Build the project.

Displaying Subcategories in the Application

Now that we've created our model and added the domain service, it's time to begin creating our application. In the following steps, we will modify the business application to display a list of product subcategories in a datagrid on the home screen.

  • Add References to the following assemblies in the ReportDemo project.
    • System.Windows.Controls.DomainServices
    • System.Windows.Controls.Data
  • In the Views folder, locate Home.xaml and double click it to open it in the designer.
  • Add the following namespace references.
    • xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
    • xmlns:domain="clr-namespace:ReportingDemo.Web"
    • xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
  • Replace the contents of the <Grid> control with the following xaml.
    Note: Don't worry if Visual Studio complains that the type 'domain:AWDomainContext' can't be found. It will successfully find it when you compile and run the application. I am unsure of why the designer fails to detect it.
    <StackPanel x:Name="ContentStackPanel">
      <riaControls:DomainDataSource 
          x:Name="subcategoryDomainDataSource"
          AutoLoad="True" 
          Width="0" Height="0"
          LoadedData="subcategoryDomainDataSource_LoadedData"
          QueryName="GetProductSubcategoriesQuery">
          <riaControls:DomainDataSource.DomainContext>
              <domain:AWDomainContext/>
          </riaControls:DomainDataSource.DomainContext>
      </riaControls:DomainDataSource>
      <sdk:DataGrid x:Name="subcategoriesDataGrid"
                    Width="800" Height="600"
                    AutoGenerateColumns="False"
                    ItemsSource="{Binding ElementName=subcategoryDomainDataSource, Path=Data}">
          <sdk:DataGrid.Columns>
              <sdk:DataGridTextColumn x:Name="subcategoryNameColumn" Binding="{Binding Path=Name}" Header="Name" Width="200"/>
              <sdk:DataGridTemplateColumn x:Name="subcategoryIDColumn" Header="Subcategory" Width="200">
                  <sdk:DataGridTemplateColumn.CellTemplate>
                      <DataTemplate>
                          <Button Content="{Binding Path=ProductSubcategoryID}" Click="Button_Click"/>
                      </DataTemplate>
                  </sdk:DataGridTemplateColumn.CellTemplate>
              </sdk:DataGridTemplateColumn>
          </sdk:DataGrid.Columns>
      </sdk:DataGrid>
    </StackPanel>
  • In the Views folder, locate Home.xaml.cs and double click it to view its code.
  • Add the following code.
    private void subcategoryDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)
    {
        if (e.HasError)
        {
            System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
            e.MarkErrorAsHandled();
        }
    }
      
    private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
      
    }

Creating the Products Report

As you may have noticed, the Button_Click event in the previous step currently contains no code. The primary goal of this application is to allow a user to click the button for a particular subcategory to generate a products report based on that subcategory. In this section, we will create the Telerik Report that will be displayed to the user.

  • Add a new folder to the ReportingDemo.Web project named Reports.
  • Right click the Reports folder and select Add -> New Item...
  • Locate and select the template for Telerik Report Q2 2010.
  • Set the name of the report to ProductsBySubcategoryReport.cs and click Add.
  • Follow these next steps to automatically generate the report using the report wizard.
    • Click Next.
    • Click Next.
    • Click the Add New Data Source... button.
      • Select Entity Data Source and click OK.
      • Select AdventureWorksEntities from the dropdown and click Next.
      • Select AdventureWorksEntities from the tree and click Next.
      • Select the Products property from the Object Context Member listing.
      • Click Finish.
    • Make sure entityDataSource1 is selected, then click Next.
    • Select Standard, then click Next.
    • Add the following fields to the report detail section.
      • Name
      • ProductNumber
      • Color
      • ListPrice
    • Click Next.
    • Select Stepped and click Next.
    • Select Civic and click Next.
    • Click Finish.
  • In the component tray, select entityDataSource1. Then, in the properties window, expand its ObjectContext property.
    • Leave AdventureWorksEntities selected and Click Next.
    • Leave AdventureWorksEntities selected again, and click Next.
    • Select the GetProductsBySubcategory(Int32 subcategoryId) method and click Next.
    • Click the dropdown for Value, and select <New Report Parameter>.
    • Click OK to create the new Report Parameter.
    • Click Finish.

Adding the Telerik Reporting Service

Telerik Reports displayed in the Silverlight Report Viewer are actually generated on the server. Due to this, you will need to provide support for the Telerik Reporting WCF Service. This service allows the Silverlight Report viewer to request and retrieve generated Telerik Reports. This service is actually separate from those provided by RIA Services and should be thought of as a separate service.

  • Follow these steps in the Telerik Reporting Documentation to add support for Telerik Reporting Service.

Adding the Report Viewer Dialog

Now that we have created our products listing report and enabled access to it via the Telerik Reporting Service, it's time to display that report in our application. In this series of steps, we will do just that.

  • Add References to the following assemblies in the ReportingDemo project.
    • Telerik.ReportViewer.Silverlight.dll (Note: This assembly should be available under the Bin folder where Telerik Reporting was installed.)
    • Telerik.Windows.Controls.dll
    • Telerik.Windows.Controls.Input.dll
    • Telerik.Windows.Controls.Navigation.dll
  • Right click the Views folder and select Add -> New Item...
    • Locate and select the template for Silverlight Child Window.
    • Set the name of the child window to ReportViewerDialog.xaml and click Add.
  • In the Views folder, locate ReportViewerDialog.xaml and double click it to open it in the designer.
    • Add the following namespace reference.
      • xmlns:telerik="clr-namespace:Telerik.ReportViewer.Silverlight;assembly=Telerik.ReportViewer.Silverlight"
    • Replace the contents of the <Grid> control with the following.
      <Grid.RowDefinitions>
          <RowDefinition />
          <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
        
      <telerik:ReportViewer  x:Name="ReportViewer1" Grid.Row="0"
            ReportServiceUri="../ReportService.svc"
            Report="ReportingDemo.Web.Reports.ProductsBySubcategoryReport, ReportingDemo.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" RenderBegin="ReportViewer1_RenderBegin">
      </telerik:ReportViewer>
      <Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
  • In the Views folder, locate and double click ReportViewerDialog.xaml.cs to view its source code.
    • Replace its code with the following.
      public partial class ReportViewerDialog : ChildWindow
      {
          int _subcategoryId;
       
          public ReportViewerDialog(int subcategoryId)
          {
              InitializeComponent();
              _subcategoryId = subcategoryId;
          }
       
          private void OKButton_Click(object sender, RoutedEventArgs e)
          {
              this.DialogResult = true;
          }
       
          private void ReportViewer1_RenderBegin(object sender, Telerik.ReportViewer.Silverlight.RenderBeginEventArgs args)
          {
              // specifies the subcategory as a report parameter to be used
              // in the generation of the report
              args.ParameterValues["subcategoryId"] = _subcategoryId;
          }
      }
  • In the Views folder, locate and double click Home.xaml.cs to view its source code.
    • Add the following code to the Button_Click event handler to display the ReportViewerDialog for the clicked subcategory.
      Button btn = sender as Button;
      int subcategoryId = int.Parse(btn.Content.ToString());
        
      ReportViewerDialog viewer = new ReportViewerDialog(subcategoryId);
      viewer.Show();

Conclusion

Whew, that was a lot to take in wasn't it? Well, now that you've completed all of these steps, you should be able to click the run button and the application should hopefully run successfully. Upon entering the home screen, you should see a listing of product subcategories generated via RIA Services. Each of these subcategories will have a corresponding button. Clicking the button will display our custom ReportViewerDialog. The silverlight report viewer contained in this dialog will send a request to the Telerik Reporting WCF service with the clicked SubcategoryID as a parameter. The Telerik Reporting WCF service will then generate and return a report to the report viewer to be displayed to the user.

Click here to download the source code.

Note: When running the demo application, make sure to set ReportingDemo.Web as the startup project. Otherwise, you might see the following dialog:

Warning Dialog


Comments

Comments are disabled in preview mode.