Silverlight 4.0: DomainDataSource

This article introduces the “DomainDataSource” available in Silverlight (using WCF RIA Services). It also discusses working with query parameters using “DomainDataSource.”

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
August 11, 2010
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

To make this article simple, I managed to create a simple Silverlight 4.0 application which consumes a WCF RIA Service created using the WCF RIA Service Library. If you are not familiar with developing applications using the WCF RIA Service Library and Silverlight 4.0, check out this beginner’s article.

The entire source code for this article is available in the form of a free downloadable zip file. The solution was developed using Microsoft Visual Studio 2010 Ultimate Edition with Microsoft Silverlight 4.0 on Windows 7 Ultimate edition.  I didn’t really test it in any other environment. I request that you post in the discussion area if you have any problems with execution.

Introducing DomainDataSource in Silverlight 4.0

In my previous articles, I explained how to deal with WCF RIA Service from Silverlight 4.0 in various ways. In this article, I would like to introduce the “DomainDataSource” object. 

“DomainDataSource” is mainly used to simplify communication between a WCF RIA Service and a Silverlight 4.0 application (without writing too much code-behind).  We can leverage “DomainDataSource” to call various operations against the WCF RIA Service using declarative syntax (XAML).

Let us start with an example. The following is the code which lays out a Silverlight DataGrid. We use this DataGrid to show information pulled from the WCF RIA Service using “DomainDataSource.”

<UserControl x:Class="SLBusinessAppWithRiaLib.DdsBasic"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:BusinessLib.Web;assembly=BusinessLib"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width="500" Height="500">
   
    <Grid x:Name="LayoutRoot" Background="White">
     <Grid.RowDefinitions>
      <RowDefinition Height="*" />
     </Grid.RowDefinitions>

        <sdk:DataGrid
            x:Name="dgEmp"
            Margin="8" MinHeight="200" IsReadOnly="True"
            AutoGenerateColumns="True" />

    </Grid>
</UserControl>


Now, let us modify the above code to work with “DomainDataSource.” The following are the steps:

• Make sure that System.Windows.Controls.DomainServices is referred.

• Add the following to the namespace section:

    xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.
DomainServices"

• Add the following code prior to the Grid (LayoutRoot) control:

    <UserControl.Resources>
        <riaControls:DomainDataSource x:Name="EmpDomDataSource"
                                      LoadSize="15"
                                      QueryName="GetEmps"
                                      AutoLoad="True">
            <riaControls:DomainDataSource.DomainContext>
                <local:EmpMgrDomainSvc></local:EmpMgrDomainSvc>
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
    </UserControl.Resources>

• Modify DataGrid to bind to DomainDataSource:

        <sdk:DataGrid
            x:Name="dgEmp"
            Margin="8" MinHeight="200" IsReadOnly="True"
            AutoGenerateColumns="True"
            ItemsSource="{Binding Data, ElementName=EmpDomDataSource}" />

Once you execute the application, the output should look like the following:

The next section explains the code available in this section.

DomainDataSource control explained

“DomainDataSource” is an advanced control which directly works against the WCF RIA service to pull or manipulate data. The main power of this control is that it can be customized declaratively (apart from supporting code-behind).

To retrieve data from the WCF RIA service, we usually start with entity queries.  The entity queries execute against a database; the result set is captured in the form of a collection (of entities), and finally put into the “context” object (declared and defined at client).

The entire process explained in the previous paragraph can be automated using a single “DomainDataSource” element.  Let us consider the following snippet (taken from the previous section):

    <UserControl.Resources>
        <riaControls:DomainDataSource x:Name="EmpDomDataSource"
                                      LoadSize="15"
                                      QueryName="GetEmps"
                                      AutoLoad="True">
            <riaControls:DomainDataSource.DomainContext>
                <local:EmpMgrDomainSvc></local:EmpMgrDomainSvc>
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
    </UserControl.Resources>

Let us try to understand the above code one step at a time:

• DomainDataSource exists in System.Windows.Controls.DomainServices assembly (in this case, the namespace is “riaControls”).

• It is logical control/element (does not have any user interface).

• DomainDataSource works closely and tightly with a DomainContext (in this case, it is “EmpMgrDomainSvc”).

• DomainDataSource pulls data into its context (defined in the previous step) using an entity query supported by the respective DomainContext (in this case, it is “QueryName”).

• Once we specify “AutoLoad=True,” the DomainContext gets automatically instantiated and executes the query specified through “QueryName.”

If we need to handle errors during communication, this can be easily achieved through code-behind as shown below:

    Private Sub EmpDomDataSource_LoadedData(ByVal sender As Object, ByVal e As System.Windows.Controls.LoadedDataEventArgs) Handles EmpDomDataSource.LoadedData
        If e.HasError Then
            System.Windows.MessageBox.Show(e.Error.ToString, "Load Error", System.Windows.MessageBoxButton.OK)
            e.MarkErrorAsHandled()
        End If
    End Sub

Working with DomainDataSource from code-behind

In previous sections, we worked with the DomainDataSource control directly using declarative syntax. In this section, we will dynamically execute a query through DomainDataSource using code-behind.

Let us create a new form as follows:

<UserControl x:Class="SLBusinessAppWithRiaLib.DdsQryCodeBehind"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.
DomainServices"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:BusinessLib.Web;assembly=BusinessLib"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width="500" Height="500">

    <UserControl.Resources>
        <riaControls:DomainDataSource x:Name="EmpDomDataSource">
            <riaControls:DomainDataSource.DomainContext>
                <local:EmpMgrDomainSvc></local:EmpMgrDomainSvc>
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
    </UserControl.Resources>
   
    <Grid x:Name="LayoutRoot" Background="White">
     <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
     </Grid.RowDefinitions>

        <Button x:Name="btnLoad" Content="Show" Width="50" Height="25" HorizontalAlignment="Left" Margin="8,8,8,8"  />
        <sdk:DataGrid Grid.Row="1"
            x:Name="dgEmp"
            Margin="8" MinHeight="200" IsReadOnly="True"
            AutoGenerateColumns="True"
            ItemsSource="{Binding Data, ElementName=EmpDomDataSource}" />

    </Grid>
</UserControl>

The design would look something like the following:

Modify the code-behind so that it looks like the following:

Imports System.ServiceModel.DomainServices.Client
Imports System.Windows.Data

Partial Public Class DdsQryCodeBehind
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnLoad.Click
        Dim oDdsrc As DomainDataSource = Me.Resources("EmpDomDataSource")
        oDdsrc.QueryName = "GetEmps"
        oDdsrc.LoadSize = 15
        oDdsrc.Load()
    End Sub

End Class

The above code is pretty self-explanatory. All we do is get the DomainDataSource, provide the QueryName and LoadSize and finally call the “Load” method to execute the query.

Modify App.xaml.vb as shown below (to work with this form):

    Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup

        Me.RootVisual = New DdsQryCodeBehind()

    End Sub

Once you execute the above form, when you click on the button, you should see the output shown below:

Working with QueryParameters using DomainDataSource

In previous sections, we worked with the DomainDataSource element with entity queries which do not have any parameters. In this section, we will try to execute entity queries with parameters using the DomainDataSource.

Let us add a partial class which extends the domain service “EmpMgrDomainSvc” (in “BusinessLib” project) as follows:

Partial Public Class EmpMgrDomainSvc

    Public Function GetEmpsByDeptno(ByVal deptno As String) As IQueryable(Of emp)
        'better to use IValueConverter in this case
        Dim iValue As Integer
        If Integer.TryParse(deptno, iValue) Then
            Return Me.ObjectContext.emps.Where(Function(c) c.deptno = iValue)
        Else
            Return Nothing
        End If
    End Function

End Class

The above adds a new method, “GetEmpsByDeptno” (with “deptno” as parameter) to “EmpMgrDomainSvc.”  Now, we try to execute the above using the “DomainDataSource.”

Let us create a new form as follows:

<UserControl x:Class="SLBusinessAppWithRiaLib.DdsQueryParam"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.
DomainServices"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:BusinessLib.Web;assembly=BusinessLib"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width="500" Height="500">

    <UserControl.Resources>
        <riaControls:DomainDataSource x:Name="EmpDomDataSource"
                                      LoadSize="15"
                                      QueryName="GetEmpsByDeptno"
                                      AutoLoad="True">
            <riaControls:DomainDataSource.DomainContext>
                <local:EmpMgrDomainSvc></local:EmpMgrDomainSvc>
            </riaControls:DomainDataSource.DomainContext>
            <riaControls:DomainDataSource.QueryParameters>
                <riaControls:Parameter ParameterName="deptno" Value="20"/>
            </riaControls:DomainDataSource.QueryParameters>
        </riaControls:DomainDataSource>
    </UserControl.Resources>
   
    <Grid x:Name="LayoutRoot" Background="White">
     <Grid.RowDefinitions>
      <RowDefinition Height="*" />
     </Grid.RowDefinitions>

        <sdk:DataGrid
            x:Name="dgEmp"
            Margin="8" MinHeight="200" IsReadOnly="True"
            AutoGenerateColumns="True"
            ItemsSource="{Binding Data, ElementName=EmpDomDataSource}" />

    </Grid>
</UserControl>

In the above code, we assigned the “GetEmpsByDeptno” query to DomainDataSource. As the “GetEmpsByDeptno” method accepts a “Deptno” parameter, we need to provide the parameter value when trying to execute the query. It was done with the following:

            <riaControls:DomainDataSource.QueryParameters>
                <riaControls:Parameter ParameterName="deptno" Value="20"/>
            </riaControls:DomainDataSource.QueryParameters>

Once we execute the above form, the output would look similar to the following:

My upcoming articles will focus on control parameters, sorting, grouping, filtering and paginating using the “DomainDataSource” element. I hope you enjoyed the article; any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com/.

blog comments powered by Disqus
SILVERLIGHT ARTICLES

- With Silverlight Gone, Whither SharePoint?
- Silverlight in the News
- Silverlight Has a Bright Future
- Windows 8 Effects on .Net and Silverlight De...
- Microsoft`s SkyDrive Abandons Silverlight
- Silverlight Developers Unhappy with Windows ...
- Best Silverlight Examples
- How to install Silverlight for Windows Phone
- Microsoft Reveals Silverlight 5 Features
- Silverlight News: SRS and Microsoft to Bring...
- Silverlight 4.0: Paging Through Data using D...
- Silverlight 4.0: Navigating Data Using Domai...
- Silverlight 4.0: Filtering Data Using Domain...
- Silverlight 4.0: Sorting and Grouping Data w...
- Silverlight 4.0: Query Parameters of DomainD...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 7 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials