Silverlight 4.0: Filtering Data Using DomainDataSource

This article gives a complete idea of the filtering features available with the “DomainDataSource” control in Silverlight (using WCF RIA Services). It discusses how to use both markup and code-behind methodologies to implement filtering against data retrieved from WCF RIA Services.

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


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

To make this article simple, I built 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 a beginner’s article.

If you are unfamiliar with “DomainDataSource,” I strongly recommend that you go through my previous articles published at http://www.aspfree.com/cp/bio/Jagadish-Chatarji

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.

Filtering data using DomainDataSource – the markup way

In my previous articles, I explained the importance of DomainDataSource and how we can query, sort and group data using the same in a Silverlight 4.0 application.  In this section, we will focus on filtering the data available in DomainDataSource. 

Let us start with an example:

<UserControl x:Class="SLBusinessAppWithRiaLib.DdsFilter"
    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="GetEmps"
                                      AutoLoad="True">
            <riaControls:DomainDataSource.DomainContext>
                <local:EmpMgrDomainSvc></local:EmpMgrDomainSvc>
            </riaControls:DomainDataSource.DomainContext>
            <riaControls:DomainDataSource.FilterDescriptors>
                <riaControls:FilterDescriptor PropertyPath="deptno" Value="30"></riaControls:FilterDescriptor>
            </riaControls:DomainDataSource.FilterDescriptors>
        </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>

Let's take a close look at the above code.  I defined a DomainDataSource named “EmpDomDataSource” which works with a Domain Service context defined as “EmpMgrDomainSvc.”  The DomainDataSource works with an entity query named “GetEmps” and loads all entities automatically (“AutoLoad” setting is set to “true”). The DomainDataSource is equipped with a FilterDescriptor, as shown below:

            <riaControls:DomainDataSource.FilterDescriptors>
                <riaControls:FilterDescriptor PropertyPath="deptno" Value="30"></riaControls:FilterDescriptor>

A FilterDescriptor accepts “PropertyPath” and a value for the property. This way, the DomainDatasource filters data based on the property and value defined in the  FilterDescriptor. Similarly, we can have any number of FilterDescriptor elements specified as part of the “FilterDescriptors” element.

Finally, DomainDataSource applies the filter, and DataGrid gets bound to DomainDataSource as shown below:

The code-behind way to filter data using DomainDataSource: form design

In the previous section, we saw how to filter data in DomainDataSource using a simple change in markup. In this section, we will try to accomplish the same using code-behind.

Let us create a new form as follows:

<UserControl x:Class="SLBusinessAppWithRiaLib.DdsFilterCodeBehind"
    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="GetEmps"
                                      AutoLoad="True">
            <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>
            <RowDefinition Height="*" />
     </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" Margin="8" >
            <sdk:Label Content="Enter Dept Number:" />
            <TextBox x:Name="txtDeptFilter" MinWidth="50" Margin="5, 0, 0, 0" />
            <Button x:Name="btnApplyFilter" Content="Apply Filter" Margin="5, 0, 0, 0" />
            <Button x:Name="btnClearFilter" Content="Clear Filter" Margin="5, 0, 0, 0" />
        </StackPanel>

        <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 for the above would look similar to the following screen shot:

The next section explains the above code.

The code-behind way to filter data using DomainDataSource: form design explanation

This section explains the code provided in the previous section.  Let us start from here:

<Grid x:Name="LayoutRoot" Background="White">
     <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
     </Grid.RowDefinitions>
.
.
</Grid>

The above markup creates a grid layout with two rows. The first row would expand based on the content, and the second occupies the rest of the area.

        <StackPanel Orientation="Horizontal" Margin="8" >
            <sdk:Label Content="Enter Dept Number:" />
            <TextBox x:Name="txtDeptFilter" MinWidth="50" Margin="5, 0, 0, 0" />
            <Button x:Name="btnApplyFilter" Content="Apply Filter" Margin="5, 0, 0, 0" />
            <Button x:Name="btnClearFilter" Content="Clear Filter" Margin="5, 0, 0, 0" />
        </StackPanel>

The above creates a stack panel which acts as a container to all controls placed next to each other in a horizontal manner. From the above, you should understand that the stack panel contains a label, a textbox and two buttons sitting next to each other.

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

Finally, we have the DataGrid, which sits in second row of the whole form. This occupies the rest of the space after the first row (with the stack panel) is rendered. It is currently bound to “EmpDomDataSource,” which is defined as follows:

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

As of now, the above simply defines a DomainDataSource which pulls information from the entity query “GetEmps.”  It does not do any filtering yet.

The code for the buttons is provided in the next section.

The code-behind way to filter data using DomainDataSource: code

This section contains the code-behind for the button discussed in the previous section.

Modify your code-behind so that it looks similar to the following:

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

Partial Public Class DdsFilterCodeBehind
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
    End Sub


    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

    Private Sub btnApplyFilter_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnApplyFilter.Click
        Me.EmpDomDataSource.FilterDescriptors.Clear()
        Dim oFilter As New FilterDescriptor With {
            .PropertyPath = "deptno",
            .Value = Me.txtDeptFilter.Text
            }
        Me.EmpDomDataSource.FilterDescriptors.Add(oFilter)
    End Sub

    Private Sub btnClearFilter_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnClearFilter.Click
        Me.EmpDomDataSource.FilterDescriptors.Clear()
    End Sub
End Class

The DomainDataSource element contains the “FilterDescriptors” collection. We can add as many filter parameters as possible to this collection. The moment we add any object to “FilterDescriptors,” DomainDataSource automatically filters data immediately, and this will be reflected automatically in the data grid.

The output for the above would look similar to the following:

Working with filter operators using DomainDataSource

In all previous sections we saw how to apply filters to a DomainDataSource using “FilterDescriptors.” All of those filters work with the “equal” condition by default. 

In detail, the property path (available as part of the FilterDescriptor) gets checked with the value we provide, and the object will be selected if and only if both match. But, I may have a scenario that is different from direct matching. For example, say I want to see all the employees that have a salary above 6000. This can be accomplished by providing filter operators as shown below:

<UserControl x:Class="SLBusinessAppWithRiaLib.DdsFilterOperator"
    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="GetEmps"
                                      AutoLoad="True">
            <riaControls:DomainDataSource.DomainContext>
                <local:EmpMgrDomainSvc></local:EmpMgrDomainSvc>
            </riaControls:DomainDataSource.DomainContext>
            <riaControls:DomainDataSource.FilterDescriptors>
                <riaControls:FilterDescriptor PropertyPath="sal" Operator="IsGreaterThan"  Value="6000"></riaControls:FilterDescriptor>
            </riaControls:DomainDataSource.FilterDescriptors>
        </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>


From the above code, you can observe that the FilterDescriptor has a new attribute, “Operator.” It is an enumeration with a pre-defined set of constants which work as operators. The output for the above would look similar to the following:

My upcoming articles will focus more on 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 6 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials