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”:
- using System.ComponentModel.DataAnnotations;
- namespace RIAServicesSharedCodeExample.Web
- {
- public partial class Person
- {
- [Key]
- public string Name { get; set; }
- [Required]
- public int Age { get; set; }
- }
- }
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.
- namespace RIAServicesSharedCodeExample.Web
- {
- public partial class Person
- {
- public int AgePlus20
- {
- get { return Age + 20; }
- }
- }
- }
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:
- namespace RIAServicesSharedCodeExample.Web
- {
- using System.Collections.Generic;
- using System.Linq;
- using System.Web.DomainServices;
- using System.Web.Ria;
- // TODO: Create methods containing your application logic.
- [EnableClientAccess()]
- public class DemoService : DomainService
- {
- private List<Person> _people = new List<Person>
- {
- new Person {Name="John", Age=25},
- new Person {Name="Jack", Age=40},
- new Person {Name="Jill", Age=30}
- };
- public IQueryable<Person> GetPeople()
- {
- return _people.AsQueryable();
- }
- }
- }
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:
- <UserControl x:Class="RIAServicesSharedCodeExample.MainPage"
- 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:RIAControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
- xmlns:ctx="clr-namespace:RIAServicesSharedCodeExample.Web"
- xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
- mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
- <Grid x:Name="LayoutRoot">
- <RIAControls:DomainDataSource x:Name="ddsDemoDataSource" QueryName="GetPeople" AutoLoad="True">
- <RIAControls:DomainDataSource.DomainContext>
- <ctx:DemoContext/>
- </RIAControls:DomainDataSource.DomainContext>
- </RIAControls:DomainDataSource>
- <data:DataGrid ItemsSource="{Binding Data, ElementName=ddsDemoDataSource}"></data:DataGrid>
- </Grid>
- </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:

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)