Deborah's Developer MindScape

         Tips and Techniques for Web and .NET developers.

November 25, 2009

Silverlight and RIA Services: Binding to a DataForm

Filed under: ASP.NET RIA Services,C#,Silverlight,VB.NET @ 4:24 pm

When building line of business (LOB) applications, a common feature is create, review, update, and delete (CRUD) operations on the data in the application. An easy way to provide this feature is using the Silverlight DataForm.

[For an introduction to Silverlight and RIA Services, start here.]

NOTE: The example used here is a continuation of the example in this prior post.

Updating the Domain Service Class

The first step in building a DataForm is to ensure that your Domain Service classes support create, update, and delete operations. The Domain Service class for this example is a CustomerService and resides in the Web project created when the Silverlight project was created.

NOTE: If you don’t add these methods, you will get exceptions when trying to work with the DataGrid such as "Unhandled Error in Silverlight Application Code: 4004" with a message "Editing items is not supported by the IEditableCollection."

In C#:

namespace SLCSharp.Web
    using BoCSharp;
    using System.Collections.Generic;
    using System.Web.Ria;
    using System.Web.DomainServices;

    public class CustomerService : DomainService
        public IEnumerable<Customer> GetCustomers()
            return Customers.Retrieve();

        public void InsertCustomer(Customer currentPerson)

        public void UpdateCustomer(Customer currentPerson)

        public void DeleteCustomer(Customer currentPerson)

In VB:

Imports System.Web.DomainServices
Imports System.Web.Ria

<EnableClientAccess()> _
Public Class CustomerService
    Inherits DomainService

    Public Function GetCustomers() As IEnumerable(Of Customer)
        Return Customers.Retrieve()
    End Function

    Public Sub InsertCustomer(ByVal currentPerson As Customer)

    End Sub

    Public Sub UpdateCustomer(ByVal currentPerson As Customer)

    End Sub

    Public Sub DeleteCustomer(ByVal currentPerson As Customer)

    End Sub
End Class

Notice that the Insert, Update, and Delete operations don’t contain any code. The code for these will be provided in a later post. In this post, the focus is on binding to the DataForm and trying out the DataForm features.

Having the methods in place, even though they are empty, allow the in-memory data to be updated and retained. This allows you to fully try out the user interface. But since there is no code within these methods, no changes are retained in the database.

Building the XAML

The XAML for building the DataForm requires two steps:

1) Defining the DomainDataSource for the data.

2) Defining the DataForm.


<UserControl x:Class="SLVB.CustomerSummaryUC"
    <Grid x:Name="LayoutRoot" Background="BlanchedAlmond">
        <riaControls:DomainDataSource x:Name="CustomerSource"
                 QueryName="GetCustomers" AutoLoad="True">
                     "{Binding Data, ElementName=CustomerSource}">

Using the DomainDataSource requires adding two namespaces and the DataForm requires adding a third namespace to the UserControl:

1) xmlns:riaControls is needed for the RIA DomainDataSource control.

NOTE: You won’t find the DomainDataSource control in the toolbox. You need to type it into the XAML manually.

2) xmlns:domain is the namespace for your Web project that launches your Silverlight application.

3) xmlns:dataFormToolkit contains the DataForm control.

Define a name for the DomainDataSource using the x:Name property. This is the name used in the binding. Also set the QueryName property to the name of the Domain Service class method that gets the data for this data source. In this case, it is the GetCustomers method.

The DomainDataSource also requires a DomainContext. This is where you define the name of the data context used by the data source. If you don’t see an appropriate context using intellisense, try rebuilding your application. Otherwise you can type in the name. It will be the same name as your Domain Service class but replacing "Service" with "Context". Since this example Domain Service class is CustomerService, the context is CustomerContext.

The next set of XAML builds a DataForm inside a StackPanel. The ItemsSource property of the DataForm defines the binding to the name of the DomainDataSource.

The result is as follows:


That could look a little nicer. It would be easier to use if the label names were correct words, if there was some help text, and the fields were in a more natural order. And does the user really need to see the CustomerId?

Updating the Business Objects

There are several ways to adjust the layout of the DataForm. The most unique technique is to update the business objects themselves. The idea behind this technique is that as the business objects change over time, they can ensure that the associated UI also changes over time. Regardless of whether you agree with this idea, here’s how you do it.

Simply add attributes to the associated properties.

In C#:

using System.ComponentModel.DataAnnotations;
namespace BoCSharp
    public class Customer
        public int CustomerId { get; set; }

        [Display(Name="Customer Type",
             Description="Select the type of customer",
        public int CustomerTypeId { get; set; }

        [Display(Name = "First Name",
             Description = "Enter the customer’s first name",
             Order = 1)]
        public string FirstName { get; set; }

        [Display(Name = "Last Name",
             Description = "Enter the customer’s last name",
             Order = 2)]
        public string LastName { get; set; }

        [Display(Name = "Email",
            Description = "Enter the customer’s primary email address",
            Order = 4)]
        public string EmailAddress { get; set; }

        public Customer()

In VB:

Imports System.ComponentModel.DataAnnotations
Public Class Customer

    Private _CustomerId As Integer
    <Display(AutoGenerateField:=False)> _
    <Key()> _
    Public Property CustomerId() As Integer
            Return _CustomerId
        End Get
        Set(ByVal value As Integer)
            _CustomerId = value
        End Set
    End Property

    Private _CustomerTypeId As Integer
    <Display(Name:="Customer Type", _
             Description:="Select the type of customer", _
             Order:=3)> _
    Public Property CustomerTypeId() As Integer
            Return _CustomerTypeId
        End Get
        Set(ByVal value As Integer)
            _CustomerTypeId = value
        End Set
    End Property

    Private _FirstName As String
    <Display(Name:="First Name", _
             Description:="Enter the customer’s first name", _
             Order:=1)> _
    Public Property FirstName() As String
            Return _FirstName
        End Get
        Set(ByVal value As String)
            _FirstName = value
        End Set
    End Property

    Private _LastName As String
    <Display(Name:="Last Name", _
             Description:="Enter the customer’s last name", _
             Order:=2)> _
    Public Property LastName() As String
            Return _LastName
        End Get
        Set(ByVal value As String)
            _LastName = value
        End Set
    End Property

    Private _EmailAddress As String
    <Display(Name:="Email", _
           Description:="Enter the customer’s primary email address", _
           Order:=4)> _
    Public Property EmailAddress() As String
            Return _EmailAddress
        End Get
        Set(ByVal value As String)
            _EmailAddress = value
        End Set
    End Property
End Class

Notice that each property now has a Display attribute. The key named parameters within this attribute are:

  • AutoGenerateField: Set to false, this will hide the field so it does not appear on the data form. If not set, the value is true.
  • Description: This is the text that will appear as a tooltip (see screen shot below). If not set, no tooltip appears.
  • Name: This is the name that will appear as the label for the field. If not set, the field name is used.
  • Order: This defines the order of the fields on the data form.

The result is as follows:


MUCH nicer!

NOTE: I also added a Margin ="5,5,200,5" to the StackPanel to ensure there was space to the right to see the information tooltip. No other changes were made to the XAML.

NOTE: When I made the changes to the business object and ran the application, the DataForm layout did not change. I recompiled the application and ran again before I saw the changes.

The only thing left to do is change the Customer Type text field to a ComboBox. But amazing, that is a significant amount of work. Better left for a future post.



  1.   Robin McNeil — November 25, 2009 @ 6:04 pm    Reply

    I am just starting to work with Silverlight and I have found your website VERY helpful. Thanks for the efforts you are making.

    As a developer of business apps., I frequently have the situation where data input through a form requires complex validation, with inter-relationships among the fields on the form. Normally, I would put this logic in the middle tier of my application and validate the resulting object before saving it to the database. If there is a problem with the validation, I would send the appropriate information to the view, perhaps by raising an exception.

    Do you have any thoughts about how this would be handled in a Silverlight app.? I guess that I could share the validation logic between my middle tier and the Silverlight app., but is there another / better way?

  2.   Hemant — November 30, 2009 @ 5:49 pm    Reply

    The Data Annotations showed up after I aligned them on one line, otherwise when I just pasted the Data Annotations, the Data Form was ignoring them.

  3.   Scott Leckie — April 23, 2010 @ 6:40 pm    Reply

    Good post – thanks. Regarding the Error 4004, I think the answer to this is to handle e.HasError in {domaincontext}_SubmittedChanges. Please see for more information. Cheers Scott

  4.   Dale — February 8, 2011 @ 6:52 pm    Reply

    I’ve found your posts to be quite useful and have just started using RIA services. Perhaps you can help me with something I am hung up on. I want to put a combobox that gets data from table 1 above a dataform that enables adding a new record to table 2. I need the Customer name and ID from Table 1 to populate the CustomerID in table 2. A new Salesman (Table 2) can’t be added to a customer that doesn’t exist… My question is – How do I bind the Table 1 ID and name to the combobox? Once I get past that I’ll have to figure out how to get the ID in the TextBox in the dataform.

  5.   Santosh — March 31, 2011 @ 8:32 am    Reply

    I am trying to add a Combo box in different data forms dymanically using the custom dataform using the custom Annotations.
    i am not able to set the Itemsource for those Combo box.
    Can any one help me to solve this issues.

  6.   Jay — July 20, 2011 @ 3:00 pm    Reply

    Where can I find teh later post…I am having issues with the Code that is needed in the InsertCustomer Sub in teh DomainService.vb page.

  7.   DeborahK — July 25, 2011 @ 10:11 am    Reply

    Hi Jay –

    You can download the example with the insert feature from here:

    Hope this helps.

  8.   hari — December 14, 2011 @ 5:12 am    Reply

    I placed Check box inside ListBox inside the Dataform. I have 3 classes(Class1, Class2,Class3). If i need to add some more Classes, i can add by clicking the + icon on the Dataform. I have 10 Items(Item1, Item2, Item3… Item10 as checkboxes in ListBox). If I select the Item2 and Item3 for Class1, the remaining 8 Items should only avail for Class2. How I could I do in MVVM.?
    Pls Anyone give solution for this…

    Thanks in Advance…

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2022 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs