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

 

 
 
 
 
 
 
 
 
 
 
 
 
 
Share

About Jesse Liberty

Jesse Liberty is an independent consultant and programmer with three decades of experience writing and delivering software projects. He is the author of 2 dozen books and multiple Pluralsight courses, and has been 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 Xamarin Certified Mobile Developer and a Xamarin MVP, Microsoft MVP and Telerik MVP.
This entry was posted in Mini-Tutorial and tagged . Bookmark the permalink.

One Response to RIA: Data Source Control

  1. David El says:

    I realize that you guys are true gods of technology. I really value what you guys have done. But sadly you seem to drift a little too far past solving the real world problems our clients are asking us to solve on a day-to-day basis, and so are passing the opportunities we really need as in-the-trenches developers.

    For example I wasted hours of time with a client assuming that RIA would work in a WPF application environment as well as in Silverlight. If RIA is really supposed to be a loosely coupled SOA solution at least wouldn’t that assumption be valid?

    I often wish that Microsoft would slow down and really work with Silverlight to make it ubiquitous. I mean we’ve been using these buzwords now – portability, scalability, extensibility, for the lifetime of IT development over the last 100 years and we still haven’t really gotten there as a interlaced Microsoft shops let alone a multi-vendor community.

    My real fear – and it is a fear since I love Sliverlight, is that Silverlight will just become another niche technology as Microsoft corners it to only fearlessly run on its own operating systems. Today it disappointingly really doesn’t work on other devices fully except through software of the third party kind – a.k.a. Nokia Moonlight. To be frank, what we really need is Microsoft to step out into the light of the technology agnostic new Day and put true Silverlight on every device like it promised it would.

    Or maybe I’m just flat out wrong and being too much of an idealist looking for a Star Trek economy and just need a long vacation. I freely admit that given the time I’ve wasted tryng to sort out what is worth spending my few years on earth with and trying to earn a reasonable and fair living at the same time.

    But you know, maybe I’m just not understanding that Microsoft is being truly visionary and will bring us all to some equitable place where technology isn’t just worshipping some new shining set of software tools — at the expense of providing affordable business solutions that really are – shall we venture to non-bull.. bingo say – “extensible”.

    I’m thinking that with the wonderful work you are doing on Silverlight this can occur in an actual standardized way that makes new software affordable to create and profit from — both as developer and someone using it to create these practical, real world solutions and not just as demoware.

    But today I can’t go create a universally accessible web site and justify using only Silverlight since I have to spend the time to creating multiple sets of code for every mobile device, and I still have to nastily make the user reboot their browser just as they are tasting my delicious site for the first time, only to kill the magic moment.

    Curiously, just using the plethora of JQUERY plug-ins out there I can do a lot of stuff that is reasonably portable. Maybe the animations aren’t quite as fancy or the corners quite as smooth and round and the blends quite as cool as with Sliverlight, but then there’s still enough pixy dust to get the users flying…

    In summary I’ve heard about the Silver light at the end of the interoperable tunnel, even on the local PC with WPF cross-compatibility with desktop apps. But I’m still not seeing it, even with version 4 working on more desktop browsers. Yes, like every other sane or insane developer I want to bury HTML and JavaScript. I want to use the same interchangable client as well as SOA code base, be it RIA or what have you. But I fear we’ll never get there. Is the reason just some technical leap that you guys are still in the process of figuring out? Or is it something more about profit margins in hording the technology? The optimist still not beaten out of me hopes for my own paranoia in thinking the latter…

Leave a Reply

Your email address will not be published.