RIA: Data Source Control

MiniTutorialLogo
ProjectTuringLogo Turing Project Page: [Novice: 11 | Advanced: 8 ]
FAQ | Table of Contents | Definitions
What is this and where do I start?

Part 3 of 3

This is the last of a three part sub-series on using Entity Frameworks and RIA Data Services to move data from our Sql Server database to our Silverlight Application’s DataGrid.

In Part 2, we explored returning an object graph by using the Entity Frameworks and by decorating the metadata for the RIA Services with the properties we wanted to retrieve from the contained object.

Until now, however, all of our code has instantiated via RIA Services context programmatically, invoked the query function programmatically, and assign the returned collection to the items source property of the data grid programmatically. In this post, I’ll look at a declarative approach.

Using the RIA Services DomainDataSource Control

We’ll begin with the program as we left it after the previous blog post, but we’ll immediately remove the three lines in blogs.xaml.cs that manipulates the data context.

   1: public partial class Blogs : Page

   2: {

   3:     //  private readonly BlogsContext bc = new BlogsContext();

   4:   public Blogs()

   5:   {

   6:     InitializeComponent();

   7:     //    bc.Load( bc.GetBlogsQuery() );

   8:     //    this.blogsDataGrid.ItemsSource = bc.Blogs;

   9:   }

Having removed the programmatic interface to the data context, let’s now open up blogs.xaml  and provide it with information about the data context by way of teh DomainDataSource  control, which we must first add to the toolbox. To do so, right-click on the Silverlight Xaml Controls tab, and then click on Choose Items.

Within the Choose Toolbox Items dialog box click on the Silverlight Components tab, and then click the browse button. Navigate to your program files ->Microsoft SDKs -> RIA Services, pick the folder for the latest version, within that:  Libraries-> Silverlight.  Double-click on System.Windows.RIA Controls.dll 

You should find that the DomainDataSource control has been added to the bottom of your list of controls; you may want to right-click and choose to sort them alphabetically.

Drag a DomainDataSource control onto the Xaml page just above the DataGrid.  By dragging it on rather than writing it yourself Visual Studio will create the namespace for you set up your using statement and your references.

The four attributes you’ll typically want to set, if no others, are the Name , LoadSize, QueryName, and the AutoLoad property. We will examine each of these in turn below.

You will also want to set the domain context property which you will do it explicitly as shown in the code that follows:

   1: <riaControls:DomainDataSource x:Name="BlogsDataSource"

   2:                               LoadSize="15"

   3:                               QueryName="GetBlogs"

   4:                               AutoLoad="True">

   5:    <riaControls:DomainDataSource.DomainContext>

   6:       <ds:BlogsContext />

   7:    </riaControls:DomainDataSource.DomainContext>

   8: </riaControls:DomainDataSource>

 

The LoadSize property instructs the DomainDataSource control as to how many records to get for each query to the database.  This allows you to fine tune the performance of your application (too small load size, and you are making many calls to the database, to larg a load size and there will be a noticeable wait for the data to arrive).

The QueryName parameter references the query We created in the RIA Services class, you will remember setting GetBlogs to include bloggers. Notice that here you use the name of the method (GetBlogs ).  Rather than “GetBlogsQuery()” as you did in C#.

Setting Autoload to true tells the DomainDataSource control to load the first set of data when it is initialized.

Note that the namespace for BlogsContext is DS as opposed to RIAControls the namespace for the DomainDataSource.  DS is a namespace that refers to the Web project (you’ll need to add that to the top of the file)

Build and run the application.  The results, that is the running application, are identical to what you had before.  However now you are not creating this programmatically but rather declaratively in the Xaml.

Sorting

Is relatively straightforward to add sorting declaratively as well. You do so by adding a sort descriptor to your DomainDataSource control.  In the case shown below (Lines 9 through 11), we are setting the SortDescriptor property explicitly, and having it sort on BlogName.

 
   1: <riaControls:DomainDataSource x:Name="BlogsDataSource"

   2:                               LoadSize="20"

   3:                               QueryName="GetBlogs"

   4:                               AutoLoad="true">

   5:    <riaControls:DomainDataSource.DomainContext>

   6:       <ds:BlogsContext />

   7:    </riaControls:DomainDataSource.DomainContext>

   8:    <riaControls:DomainDataSource.SortDescriptors>

   9:       <riaData:SortDescriptor PropertyPath="BlogName"

  10:                               Direction="Ascending" />

  11:    </riaControls:DomainDataSource.SortDescriptors>

  12: </riaControls:DomainDataSource>

Sending the sort column in this way it causes the data grid to open with that column sorted.  The user, of course, can sort on any column by clicking on the column header.

Filtering

Before we leave the DomainDataSource control, let’s take a quick look at filtering, which works much like sorting. Sorting the grid In this case rather than explicitly putting into our filter what it is we are filtering on, we will instead set the “Control Parameter” to point to another control on the same page that will provide the text on which to sort.

To begin, we’ll add a text box into which the user can type the desired filter.

<StackPanel Orientation="Horizontal"

            HorizontalAlignment="Right"

            Margin="0,-16,0,0">

   <TextBlock VerticalAlignment="Center"

              Text="Name Contains Filter" />

   <TextBox x:Name="filterText"

            Width="75"

            FontSize="11"

            Margin="4"

            Text="Silverlight" />

</StackPanel>

 

This code can be placed directly above the DomainDataSource, and as you can see it provides a textblock with a prompt and a text box, which will gather in the desired filter. Next We’ll add a FilterDescriptors element to the DomainDataSource control, and tell it to get its value from that text box:

   1: <riaControls:DomainDataSource x:Name="BlogsDataSource"

   2:                               LoadSize="20"

   3:                               QueryName="GetBlogs"

   4:                               AutoLoad="true">

   5:    <riaControls:DomainDataSource.DomainContext>

   6:       <ds:BlogsContext />

   7:    </riaControls:DomainDataSource.DomainContext>

   8:    <riaControls:DomainDataSource.SortDescriptors>

   9:       <riaData:SortDescriptor PropertyPath="BlogName"

  10:                               Direction="Ascending" />

  11:    </riaControls:DomainDataSource.SortDescriptors>

  12:    <riaControls:DomainDataSource.FilterDescriptors>

  13:       <riaData:FilterDescriptorCollection>

  14:          <riaData:FilterDescriptor PropertyPath="BlogName"

  15:                                    Operator="Contains">

  16:             <riaData:ControlParameter ControlName="filterText"

  17:                                       PropertyName="Text"

  18:                                       RefreshEventName="TextChanged" />

  19:          </riaData:FilterDescriptor>

  20:       </riaData:FilterDescriptorCollection>

  21:    </riaControls:DomainDataSource.FilterDescriptors>

  22: </riaControls:DomainDataSource>

 

The filter descriptors begin online 12 and run through line 21.  Notice on lines 14 and 15 that you are indicating which property is being filtered on and that you have your choice of operators such as contains, is, etc.  On lines 16 through 18, you indicate the name of the control that has the filter, the name of the property of the control from which to extract the filter, and the event on which you will update the filter.

N.B.: the code is showing updates each time a letter is typed in the text box.  This will cause a call to the database for every letter that’s typed.  You can solve this by using the Load Delay parameter.  Of course having a low delay will make the page initially load more slowly, so you may want to add the load delay programmatically after you initialize the page.

 

Finally to give it a bit of polish, let’s add a DataPager, just below the DataGrid.  Note that the binding for the DataPager is identical to that for the DataGrid, and that the DataPager retrieves 10 records at a time; we’ll go up so that and change the DomainDataSource load size to 30, so that it will retrieve 3 pages-worth at a time.

<data:DataPager PageSize="10" 

  Source="{Binding Data, ElementName=BlogsDataSource}"  />

 

SortedAndFiltered

 

 
 
 
 
 
 
 
 
 
 
 
 
 

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Mini-Tutorial and tagged . Bookmark the permalink.

One Response to RIA: Data Source Control

Comments are closed.