(X) Hide this Join our next live webinar session by Braulio Diez - Sketchflow in Real Scenarios, on Sept 29th, 8am - 9am PDT.
Learn More | Sign Up | More Webinars by SilverlightShow

Recommended

Skip Navigation LinksHome / Articles / View Article

Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource

+ Add to SilverlightShow Favorites
4 comments   /   posted by Martin Mihaylov on Apr 01, 2009
(1 votes)
Categories: Demos , Learn , Tutorials , QuickStarts

Introduction

By now we have discussed the preparations around the project, how to add a DomainService that contains our business logic and combine it with the entity framework. If you have missed one of the previous articles you can find them here:

Creating applications with .NET RIA Services Part 1 - Introduction

Creating applications with .NET RIA Services Part 2 - Creating the project

Creating applications with .NET RIA Services Part 3 - Adding a DomainService class

As you know from the previous articles in order to demonstrate the features of the .NET RIA Services I am creating the Web Administration Tool from ASP.NET in Silverlight. In this article I am going to create the Manage Users page and add the functionality needed to visualize Data. For that purpose I will need the DataGrid control, the new DataPager control and the DomainDataSource that is a part of the .NET RIA Services framework.

Here is a link to the live demo at this stage and the source code. Note that they will be updated with each article! ;)

Adding the DomainDataSource control

The DomainDataSource control can be found in the Systems.Web.Ria.Controls assembly and we have to declare the proper namespace in order to use it:

<navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           ...
           xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
           ...
           Title="ManageUsers Page">
    <Grid x:Name="LayoutRoot">
        ...
        <ria:DomainDataSource x:Name="UsersDataSource"></ria:DomainDataSource>
        ...
    </Grid>
</navigation:Page>

The next step is to configure the DomainDataSource control to work with our DomainService class named UsersManager, which we have created in the previous article. The only thing we have to do is to set the DomainContext property:

<navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           ... 
           xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
           xmlns:local="clr-namespace:WebAdministrationTool"
           ...
           Title="ManageUsers Page">
<Grid x:Name="LayoutRoot">
    ...
    <ria:DomainDataSource x:Name="UsersDataSource" LoadMethodName="LoadAspnet_Users">
        <ria:DomainDataSource.DomainContext>
            <local:UsersManager />
        </ria:DomainDataSource.DomainContext>
    </ria:DomainDataSource>
    ...
</Grid>
</navigation:Page>

As the UsersManager class can be accessed through the generated code on the client we declare the namespace of our project in the XAML. We also specify the method that the DomainDataSource should use in order to load the data from the data base. Note that on the server our method is named GetAspnet_Users, but on the client it’s LoadAspnet_Users (see in the previous article how to use the DomainService on the client by using the managed code).

Adding a DataGrid control to the scene

Now as we have our DomainDataSource control prepared let’s add a Grid and bind them together:

<data:DataGrid x:Name="UsersGrid" 
                       IsReadOnly="True" 
                       AutoGenerateColumns="False" 
                       HeadersVisibility="None" 
                       GridLinesVisibility="None">
    <data:DataGrid.ItemsSource>
        <Binding ElementName="UsersDataSource" Path="Data" />
    </data:DataGrid.ItemsSource>
    <data:DataGrid.Columns>
        <data:DataGridTextColumn Binding="{Binding UserName}" />
    </data:DataGrid.Columns>
</data:DataGrid>

Using the Element-to-Element binding that came with Silverlight 3 we bind the ItemsSource of the DataGrid to the Data property of the DomainDataSource control.

Now let’s add a row details to our DataGrid, which will give more information about the selected user. First let’s take a look at the GetAspnet_Users of the UsersManager DomainService on the server:

public IQueryable<aspnet_Users> GetAspnet_Users()
{
    return this.Context.aspnet_Users;
}

It returns the content of the aspnet_Users table. In this table the only information we have is the username. The email, the comment and if the user is active can be found in the aspnet_Membership table and the information about the roles, that the user is in, is located in the aspnet_UsersInRoles table. These two tables are in relation with the aspnet_Users table and the associations between them are defined in the data model, so we can modify the get method in the following way:

public IQueryable<aspnet_Users> GetAspnet_Users()
{
    return this.Context.aspnet_Users.OrderBy( "it.UserName" )
                       .Include( "aspnet_Membership" )
                       .Include( "aspnet_UsersInRoles" );
}

In the previous article we configured the metadata for the aspnet_Users, so we can now use the following properties on the client:

internal sealed class aspnet_UsersMetadata
{
    ...
    [Include]
    public aspnet_Applications aspnet_Applications;
 
    [Include]
    public aspnet_Membership aspnet_Membership;
 
    [Include]
    public EntityCollection<aspnet_UsersInRoles> aspnet_UsersInRoles;
    ...
}

When the query is executed they are populated with the proper data. Now back on the client we have the following row details template for the DataGrid:

<data:DataGrid x:Name="UsersGrid"
               IsReadOnly="True"
               AutoGenerateColumns="False"
               HeadersVisibility="None"
               GridLinesVisibility="None">
        ...
    <data:DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBlock x:Name="IsActiveLabel" Text="Is active:  " FontWeight="Bold" Grid.Column="0" Grid.Row="0" />
                <TextBlock x:Name="IsActiveBlock" 
Text
="{Binding aspnet_Membership.IsApproved,Converter={StaticResource BooleanConverter}}"
Grid.Column="1" Grid.Row="0" />
                <TextBlock x:Name="EmailLabel" Text="E-mail: " FontWeight="Bold" 
Grid.Column="0" Grid.Row="1" />
                <TextBlock x:Name="EmailBlock" Text="{Binding aspnet_Membership.Email}" 
Grid.Column="1" Grid.Row="1" />
                <TextBlock x:Name="DescriptionLabel" Text="Description: " FontWeight="Bold" 
Grid.Column="0" Grid.Row="2" />
                <TextBlock x:Name="DescriptionBlock" Text="{Binding aspnet_Membership.Comment}" 
Grid.Column="1" Grid.Row="2" />
            </Grid>
        </DataTemplate>
    </data:DataGrid.RowDetailsTemplate>
    ...
</data:DataGrid>

That’s it!

Paging the data

There is one last thing left to do – to add paging to the DomainDataSource. That can be easily accomplished by using the DataPager control (introduced with Silverlight 3). The control is located in the System.Windows.Controls.Data.DataForm assembly, so once again we have to declare a namespace in our XAML:

<navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            ...
           xmlns:validation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm"
            ...
           Title="ManageUsers Page">
    <Grid x:Name="LayoutRoot">
        ...
        <validation:DataPager x:Name="UsersPager"
                              PageSize="10" 
                              Source="{Binding Data, ElementName=UsersDataSource}" />
    </Grid>
</navigation:Page>

Once bound to the Data property of the DomainDataSource control it handles the paging itself, we just have to set its page size. The most important thing to mention is that the DataPager control can page collections which implement the IPagedCollectionView interface. The Data property is such a collection.

Also here the LoadSize property of the DomainDataSource control can be found useful. It determines the count of the items to be loaded in the Data property of the control. For example I can set it to 10 and each time the page is changed only 10 items will be loaded. In the common case we set it to a number multiple to the page size. Another option is to set it to the count of the items, if it is known, so all items will be loaded and no other requests to the server will be made.

Note: The DataPager doesn't work with unsorted collections, because the Skip and Take extension methods, that the control uses, are unavailable for such them. By default the EntityFrameowrk returns unsorted data and that's why I have added an OrderBy to my query. The other way is to sort the data on the client via the DomainDataSource control, but that will be the subject of my next article.

Conclusion

In this article I explained some basics about the DomainDataSource, the DataGrid and the DataPager controls. Thanks to them the loading and the visualization of data is not as tough as it was before. In the next article we’ll see how they allow us to easily apply sorting and filtering to the loaded data.

If you have any questions, I’ll be glad to answer them. :)

Share


Comments

Comments RSS RSS
  • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

    posted by Rob on Apr 04, 2009 01:38
    Is it possible to use .Net RIA Services with Azure Table Storage.
  • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

    posted by Jonathan on May 29, 2009 19:02
    I get an error whenever I try to add the domain datasource to my xaml file:
    http://silverlight.net/forums/p/99299/226646.aspx#226646

    do you have any ideas about this?

  • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

    posted by silverlight man on Jun 20, 2010 12:14

    I get this error when i make a getaspnetUser :

    Problem in mapping fragment starting at lines 67 , 75 :

    Foreign key constraints FK_aspnet_Us_Role from table aspnet_UserInRoles (RoleId) to table aspnetRoles

    Insufficent mapping : foreing key must be mapped to some associationSet etc....

  • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

    posted by anonymous on Jun 21, 2010 09:53

    Your project doesn't work in silverlight 4.0 and RIA 1.0 with visual studio 2010...

     

Add Comment

 
 

   
  
  
   
Please add 2 and 1 and type the answer here: