Tuesday, September 15, 2009

Initializing distinct XAMLs included in a single XAP

So I had a situation where I had to load multiple charts on my custom page default.aspx within Microsoft Dynamics CRM. These charts rendered different reporting data after fetching it using the MS CRM webservices.
I used silverlight visifire charts for each of my reports. Instead of creating a different silverlight application for each of my reports, I instead created different XAMLs for each of them and compiled a single XAP. Well, this is a well tried and tested approach used in any silverlight application or any aspx application using Silverlight controls which involves multiple XAMLs compiled in a single XAP. These are the steps I used:

1. Created a Silverlight application that contained multiple XAMLs each one including a different report (i.e. a different visifire chart) and compiled it as one "SLDashboardPOC.xap".

2. For each of the reports to be rendered, I embedded the compiled Silverlight XAP control multiple times in my default.aspx as follows:

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div>
<asp:Silverlight ID="Xaml1" runat="server" Source="~/SL/SLDashboardPOC.xap"
MinimumVersion="2.0.31005.0" Width="66%" Height="50%" />



<asp:Silverlight ID="Xaml2" runat="server" Source="~/SL/SLDashboardPOC.xap"
MinimumVersion="2.0.31005.0" Width="66%" Height="80%" />
.
.
.
and so on..

Now, at the time of rendering the reports I had to specify to my embedded XAP(s) which XAML page to initialize and render. I fetched datasets for different reports using the MS CRM web services from my business tier and converted them into XMLs using dsReportData.GetXml().ToString(). Then I passed these distinct dataset XMLs as parameters to the different visifire charts included in my XAP. I did this on my Page_Load by sending the datasets to my silverlight app as follows:

String strData1 = GetDataForReport1(); //This will return the dataset XML from MS CRM
initParams = "ReportParam1=" + strData1; //Create "Key=Value" Initialization parameters
Xaml1.InitParameters = initParams; //Add these to the collection of initparameters for the specific report

String strData2 = GetDataForReport2();
Xaml2.InitParameters = "ReportParam2=" + strData2;

4. Then I used these parameters in my Silverlight application's Application_Startup event to add them to the application's resources as follows:

if (e.InitParams.Count > 0)
{
foreach(var item in e.InitParams)
{
this.Resources.Add(item.Key , item.Value ); //Add each of the "Key=Value" pairs paased from the hosting page
}
}

if (e.InitParams.ContainsKey("ReportParam1"))
{
this.RootVisual = new Report1(); //This will define which XAML will be the default for the XAP. I specify a different RootVisual property for rendering each of the charts
}
if (e.InitParams.ContainsKey("ReportParam2"))
{
this.RootVisual = new Report2();
}

5. And finally while initializing my chart and rendering data, I used the applications' resources to fetch the report parameter that contained the dataset XML my chart required:
if (App.Current.Resources.Contains("ReportParam1"))
{
//Add data points to the chart and render it
{
}

No comments:

Post a Comment