Dynamically binding Report Viewer Control to un-typed datasets

 

 

Solution Plan:

1. Drop a ReportViewerControl to your favorite web-form

2. Drop a new DataSet in the project (DataSet1)

3. Create a DataTable in DataSet's XSD (DataSet1.xsd) which should define the structure of <Books.xml>

    I created Table1 which defines 2 types. I guess 2 are enough!!

    - Book_ID (of type System.Int32)

    - Title (of type System.String)

4. Drop a new RDLC file to project.

   You will notice the DataSet1 and DataTable1 being shown in "WebSite Data Sources"

     + DataSet1

         - DataTable1

                 - Book_Id

                 - Title

 

5. Drop a table to it.

    Drag and drop the Fields ( Fields!Book_ID.Value and Fields!Title.Value)

6. use the CODE LISTING 2 in Page_Load.

NOTE: Pay attention to this line:

Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WebForms.ReportDataSource("DataSet1_DataTable1", Dt))

DataSet1_DataTable1 is the link to this hack. We are telling ReportViewer to bind this table "Dt" of ours (which you might have got from somewhere) to a dataset which is understood by RDLC.

Note: You do not have to chose this RDLC in "ReportViewer Tasks". Which means rsweb:ReportViewer component is free to chose it's local report in runtime. Check the neat rsweb:ReportViewer component in CODE LISTING 3.

Here is how it looks when you bind it in design mode. But these all we are doing in RUN TIME.

<rsweb:ReportViewer ID="ReportViewer1" runat="server" Height="499px" Width="861px" >

<LocalReport ReportPath="Report1.rdlc">

<DataSources>

<rsweb:ReportDataSource DataSourceId="ObjectDataSource1" Name="DataSet1_DataTable1" />

</DataSources>

</LocalReport>

</rsweb:ReportViewer>

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetData"TypeName="DataSet1TableAdapters."></asp:ObjectDataSource>

 

 

CODE LISTING 1: Books.Xml

[XML]

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE BookRoot SYSTEM "E:\Projects\XML TRAINING\Day 1\XML Examples\books.dtd">

<BookRoot>

   <Book ISBN="Ind-123-4-5" Date="3.14 mod 5">

          <Author AuthID="a1">

                   <Name WorkedWith="a2">William</Name>

                    <Location>GB</Location>

          </Author>

          <Author AuthID="a2">

                    <Name WorkedWith="a1">Dennis</Name>

                    <Location>USA</Location>

          </Author>

          <Title>As you like it</Title>

           <Price>100$</Price>

            <SoldAt CountryId="GB">GB</SoldAt>

            <SoldAt CountryId="US">US</SoldAt>

            <SoldAt CountryId="INDIA">India</SoldAt>

             <Publisher>Tech Media</Publisher>

    </Book>

</BookRoot>

[\XML]

 

CODE LISTING 2:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

ReportViewer1.ProcessingMode = ProcessingMode.Local

     Dim rep As LocalReport = ReportViewer1.LocalReport

     rep.ReportPath = "Report1.rdlc"

     ' Lets get a dataset

      Dim ds As DataSet = New DataSet("DynDS")

      ds.ReadXml(HttpContext.Current.Request.MapPath(".\Books.xml"))

      Dim Dt As New DataTable()

Dt = ds.Tables(0)

      'Table name = Book

      Me.ReportViewer1.LocalReport.DataSources.Clear()

      Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WebForms.ReportDataSource("DataSet1_DataTable1", Dt))

End Sub

 

CODE LISTING 3: Just for reference, how your aspx page's HTML should look like.(completly unneccesary)

 <body>

<form id="form1" runat="server">

<rsweb:ReportViewer ID="ReportViewer1" runat="server" Height="499px" Width="861px">

</rsweb:ReportViewer>

</form>

</body>