Binding To Computed Properties With RIA Services Code Sharing

By John at October 03, 2009 23:33
Filed Under: Techy

I question came up over at silverlight.net that I wrote an example for.  The scenario is that we want to bind our RIA Service data context to a DataGrid control via a DomainDataSource.  We also want to have an extra column which computes a value based on other data that exists in each row.

My approach to this scenario is to utilize the code sharing feature of RIA Services to pass across a property which computes the value on client-side.  As you will see, the DataGrid and DomainDataSource accommodate this approach rather nicely.

We’re going to keep things simple on the server-side for this example and not associate our Domain Service to any entities in a database.  So add a new DomainService called “DemoService” but don’t associate it with any data.

Ok now that we have a Domain Service, lets create an entity object to work with in a class file called “Person.cs”:

  1. using System.ComponentModel.DataAnnotations;
  2. namespace RIAServicesSharedCodeExample.Web
  3. {
  4.     public partial class Person
  5.     {
  6.         [Key]
  7.         public string Name { get; set; }
  8.         [Required]
  9.         public int Age { get; set; }
  10.     }
  11. }

 

So now we have a very basic person class (“entity” to our Domain Service).  Note that this is made as a partial class purposefully.  Next let’s create another class file, call it “Person.shared.cs”.  The syntax of the name is important here, because RIA Services will not reflect the code over to client-side unless it is contains the “.shared” part.

  1. namespace RIAServicesSharedCodeExample.Web
  2. {
  3.     public partial class Person
  4.     {
  5.         public int AgePlus20
  6.         {
  7.             get { return Age + 20; }
  8.         }
  9.     }
  10. }

 

What we’ve done here is extend our partial Person class  by adding a property which adds 20 years to the Age property.  This property will not be sent down the wire when the client makes a call to our Domain Service.  Because it is “shared code”, the client-side copy of it will be merged with the entity.  What a great way to reduce network load.

Next we will prepare our Domain Service (which we created earlier “DemoService.cs” so that we can make calls to it from client-side:

 

  1. namespace RIAServicesSharedCodeExample.Web
  2. {
  3.     using System.Collections.Generic;
  4.     using System.Linq;
  5.     using System.Web.DomainServices;
  6.     using System.Web.Ria;
  7.     // TODO: Create methods containing your application logic.
  8.     [EnableClientAccess()]
  9.     public class DemoService : DomainService
  10.     {
  11.         private List<Person> _people = new List<Person>
  12.                                            {
  13.                                                new Person {Name="John", Age=25},
  14.                                                new Person {Name="Jack", Age=40},
  15.                                                new Person {Name="Jill", Age=30}
  16.         };
  17.         public IQueryable<Person> GetPeople()
  18.         {
  19.             return _people.AsQueryable();
  20.         }
  21.     }
  22. }

 

As can be seen, I’ve added a private field which is essentially our “database” to the Domain Service.  Next we create the query method which allows our client-side RIA context to be bound to the DomainDataSource in xaml.  The syntax of the name is important here as well, because RIA Services interpretes the word “Get” to understand that the GetPeople method is a query method, and not another type of RIA operation like Insert, Update, or Delete.  If you don’t want to use this syntax, that’s ok, but you’ll have to mark your method with a “[Query]” attribute.

Ok now let’s move to client-side and finish this up.  Here is the xaml for our view:

  1. <UserControl x:Class="RIAServicesSharedCodeExample.MainPage"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.             xmlns:RIAControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
  7.             xmlns:ctx="clr-namespace:RIAServicesSharedCodeExample.Web"
  8.             xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
  9.    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  10.   <Grid x:Name="LayoutRoot">
  11.         <RIAControls:DomainDataSource x:Name="ddsDemoDataSource" QueryName="GetPeople" AutoLoad="True">
  12.             <RIAControls:DomainDataSource.DomainContext>
  13.                 <ctx:DemoContext/>
  14.             </RIAControls:DomainDataSource.DomainContext>
  15.         </RIAControls:DomainDataSource>
  16.         <data:DataGrid ItemsSource="{Binding Data, ElementName=ddsDemoDataSource}"></data:DataGrid>
  17.     </Grid>
  18. </UserControl>

 

Pretty basic.  Add a DomainDataSource control, and reference your RIA data context to it (“DemoContext”).  Now add a DataGrid control and bind the DomainDataSource to it’s ItemSource property using Element binding.

And here is our result:

riaservicessharedcoderesult

As you can see, our computed property is visible in it’s own column and is properly transforming the Age column from each row.  Here is the source code:

RIAServicesSharedCodeExample.zip (1.62 mb)

Comments

10/4/2009 3:54:14 AM #

Philip Vanstraceele

Hello ,
Great stuff ! You are the best .
When I ' m running your application it works fine.
But in my application I 'm working with a 'ADO.NET Enitity Model' connected to a sql database ( created by the wizard).
Which class of these I need to name with the "share name"?
The extra property I created is recognized by the LINQ statements; But when I running the grid with the silverlight page,  I always get returned a "0" -value, for this new property. What I 'm doing wrong ?

Could it be possible to give an example with a 'ADO.NET Enitity Model' ? If it is not too much demand

Many thanks,

Philip

Philip Vanstraceele Belgium |

10/5/2009 8:08:48 AM #

John

Glad you found it at least somewhat useful.  Perhps it would be better if you could send me your project and I'll take a look to see if I can spot where the issue is?  You can attach a zip file to the contact form of this blog.

John United States |

10/4/2009 6:28:58 PM #

Kasimier Buchcik

One could improve the example you provided by implementing property update notifications for the dependent property "AgePlus20" whenever the property "Age" changes - either by using the generated partial OnXXXChanged() methods or any other mechanisn (e.g. forums.silverlight.net/forums/t/128616.aspx).

Kasimier Buchcik Germany |

10/5/2009 8:05:48 AM #

John

Good point.  I was just trying to keep this example very basic and focused on the scenario.

John United States |

Comments are closed

What is myOSity?

myOSity is a On-Demand Operating System that runs in your browser.  You can run applications, work with files, keep in touch and share things with your friends, and more.  The goal of myOSity is to combine the best aspects of operating systems and social networking, while hopefully leaving out all the annoying stuff.

Curious?

To check out myOSity for yourself click here.

Have a game or other Silverlight project that you want to become part of the growing list of applications on myOSity? Contact Me for details.

Join The Team!

Currently looking for other developers interested in being a part of the project.  Contact Me for details or read this post.

About John

I am the founder and lead designer of myOSity.com.  I've been a technologist, in one form or another, for over 20 years.

Protected by Commentor
0 comments approved
4 spam caught
Since December 1, 2008
Powered by Spam Counter