Silverlight2.0 Nested DataGrid using Silverlight-enabled WCF Services and LINQ to SQL

May 13, 2009 at 7:39 pm 2 comments

Create new project.

  1. Create a new Silverlight project in Visual Studio 2008 or Visual Web Developer 2008 and select a new Web Site to host the Silverlight application. Name it “Silverlight_MasterDetailsGrid”
  2. When the IDE opens, we have 2 projects listed. Silverlight_MasterDetailsGrid and Silverlight_MasterDetailsGrid.Web. The Web application has a Silverlight_MasterDetailsGrid.TestPage.aspx which hosts the .zap file created by Silverlight_MasterDetailsGrid.

Add Linq to SQL Classes

  1. Select Silverlight_MasterDetailsGrid.Web project in Solution Explorer and right click to add new item.
  2. Select “LINQ to SQL Classes”.
  3. Name the File to “Nwind.dbml”  and click OK
  4. Drag and Drop the Orders and Order_Details table from Server Explorer.
  5. Right click on any blank space in Nwind.dbml file and select “Properties”.
  6. Set SerializationMode to “Unidirectional”. [Currently, WCF does not support Cyclic Reference Serialization (like in dbml file the Order Table contains a Order_Detail filed and Order_Detail Table contains the Order field. Setting the SerializationMode to Unidirectional will serialize only tables excluding the referential table/fields)
  7. Click Save. [The Nwind.Designer.VB file will have all the classes with the DataContract attribute applied to Order and Order_Detail tables and DataMember attribute to the properties of these tables. This will make these classes serializable thus ready to be used in WCF Services]

Add WCF Service.

  1. Select Silverlight_MasterDetailsGrid.Web project in Solution Explorer and right click to add new item.
  2. Select “Silverlight-enabled WCF Service”
  3. Name the file “WCFService.svc” and click “OK”
  4. The Visual Studio will open the WCFService.svc.vb file with a class with dummy Service Contract and Operation Contract.
  5. Click “Project” menu and select “Add New Item”.
  6. Select Interface and Name it “IWCFService.vb”. Click “OK”
  7. Imports two Interfaces, System.ServiceModel and System.ServiceModel.Activation
  8. Add ServiceContract attribute to IWCFService Interface and define two OperationContracts GetOrders and GetAllOrderDetails. Thus the IWCFService.vb should look like:
Imports System.ServiceModelImports System.ServiceModel.Activation<ServiceContract()> _

Public Interface IWCFService

<OperationContract()> _

Function GetOrders() As IEnumerable(Of Order)

<OperationContract()> _

Function GetAllOrderDetails() As IEnumerable(Of Order_Detail)

End Interface

 9.  Open WCFService.svc.vb and delete all content of the Class and its ServiceContract attribute.

10.  Implement IWCFService Interface in the WCFService Class. This class will have only one attribute [AspNetCompatibilityRequirements].

11.  Implement the GetOrders and GetAllOrderDetails functions

12.  The WCFService.svc.vb should now look like:

Imports System.ServiceModelImports System.ServiceModel.Activation<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _

Public Class WCFService

    Implements IWCFService

    Public Function GetOrders() As IEnumerable(Of Order) Implements IWCFService.GetOrders

        Dim DC As New NwindDataContext()

        Return DC.Orders.AsEnumerable()

    End Function

 Public Function GetAllOrderDetails() As IEnumerable(Of Order_Detail) Implements IWCFService.GetAllOrderDetails

        Dim DC As New NwindDataContext()

        Return DC.Order_Details.AsEnumerable

    End Function

End Class

13.  Open Web.Config file and change the Contract in Endpoint section from Silverlight_MasterDetailsGrid.Web.WCFService to Silverlight_MasterDetailsGrid.Web.IWCFService

 This finalizes our WCF service and makes it ready to be hosted.

Defining the Service Reference in client to consume the above created WCFService

  1. In the Solution Explorer, expand the “Silverlight_MasterDetailsGrid” project. Right click on it and click “Add Service Reference”.
  2. Click “Discover” to locate the WCFService automatically.
  3. Name the Service “NwindWcfReference”

Adding DataGrid to Silverlight application

  1. Open Page.xaml and drag and drop the DataGrid from ToolBox to the Code window, under LayoutRoot grid.
  2. Name the DataGrid by adding x:Name attribute to “GrdOrders”.
  3. Set AutoGenerateColumns to True.
  4. Set ItemsSource to “{Binding}”. This will bind the DataGrid to its DataContext.

Thus, the DataGrid definition should look like:

<data:DataGrid x:Name=”GrdOrders” AutoGenerateColumns=”True” ItemsSource=”{Binding}”/>

Binding GrdOrders DataGrid to Orders

  1. Open Page.xaml.vb.
  2. Imports Silverlight_MasterDetailsGrid.NwindWcfReference
  3. Imports System.Collections.ObjectModel
  4. Add a class level variable Orders of type ObservableCollection(Of Order)
  5. Add another class level variable wcfClient of type WCFServiceClient
  6. In the constructor initialize the Orders and wcfClient variables after InitializeComponent()
  7. In the Page_Loaded event add the event handler to the wcfClient, using AddHandler WcfClient.GetOrdersCompleted, AddressOf GetOrdersCompleted
  8. Call the WcfClient.GetOrdersAsync() method
  9. Define the GetOrdersCompleted method Public Sub GetOrdersCompleted(ByVal sender As Object, ByVal e As GetOrdersCompletedEventArgs)
  10. Set Orders = e.Result
  11. Set GrdOrders.DataContext = Orders

Run the application and see the all records with all the columns of Orders table are displayed in the DataGrid.

Defining RowDetailsTemplate to create nested DataGrid

  1. Open the Page.xaml and add the RowDetailsTemplate to GrdOrders.
  2. Define the DataTemplate.
  3. Add DataGrid to DataTemplate and name it GrdDetails.
  4. Set it’s AutoGenerateColumn property to “True”

Thus the resulting XAML of Complete DataGrid should look like:

<data:DataGrid x:Name=”GrdOrders” AutoGenerateColumns=”True” ItemsSource=”{Binding}”>

<data:DataGrid.RowDetailsTemplate>

<DataTemplate>

<data:DataGrid x:Name=”GrdDetails” AutoGenerateColumns=”True” ItemsSource=”{Binding Order_Details}”></data:DataGrid>

</DataTemplate>

</data:DataGrid.RowDetailsTemplate>

</data:DataGrid>

Calling the GetAllOrderDetailsAsync and binding the inner DataGrid to Order_Detail

  1. Add another class level variable allOrder_Detais of type ObservableCollection(Of Order_Detail)
  2. In the Page_Loaded event, add the WcfClient.GetAllOrderDetailsCompleted handler.
  3. In the GetOrdersCompleted event, make a call to WcfClient.GetAllOrderDetailsAsync()
  4. Define the GetAllOrderDetailsCompleted and add following code that
    1. Fetches all the rows and columns of the Order_Details table and store it in allOrder_Detais variable.
    2. Loop through all the Order in Orders and using LINQ query find all the OrderDetails from allOrder_Detais whose OrderId is equal to Order.OrderID
    3. Create a temporary ObservalbleCollection(of Order_Detail) and insert items of Order_Detail fetched in steps b.
    4. Assign the temporary collection created in steps c to Order.Order_Details
    5. Set the GrdOrders.DataContext to Orders

The resulting GetAllOrderDetailsCompleted function should be:

Public Sub GetAllOrderDetailsCompleted(ByVal sender As Object, ByVal e As GetAllOrderDetailsCompletedEventArgs)

allOrder_Detais = e.Result

For Each o As Order In Orders

Dim tempOrder_Details = From allDetails In allOrder_Detais Where allDetails.OrderID = o.OrderID Select allDetails

Dim tempDetails As New ObservableCollection(Of Order_Detail)

For Each item In tempOrder_Details

tempDetails.Add(item)

Next

o.Order_Details = tempDetails

Next

GrdOrders.DataContext = Orders

End Sub

OUTPUT: Click any row of Master DataGrid to display the related OrderDetails in nested DataGrid.

SilverlightNestedDataGrid

Advertisements

Entry filed under: Silverlight. Tags: , , , , , , .

Sending Objects from .ASPX page to Silverlight

2 Comments Add your own

  • 1. Sunil  |  October 27, 2009 at 5:30 pm

    Hi,
    Thanks for such a very nice article, if possible can you plz mail an example program of Nested Datagrid . It will be of great help if you can send me an example of it.

    Thanks in advance

    Reply
  • 2. Lakshmi  |  June 11, 2010 at 1:12 pm

    hi..

    Article is good.

    Can you please povide the solution?

    or atleast a sample solution which directly binds some static data, instead of using WCF and linq?

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Recent Posts


%d bloggers like this: