This article will demonstrate how to add, edit, delete, group, sort, filtering data using ComponentWays Silverlight xamlDataGrid and RIA Services (DomainDataSource).
Content
- Starting a New Project
- Exposing Data from Entity Framework
- Consuming Data in the Client with DomainDataSource and xamlDataGrid
- CRUD: Add, Edit, View, Delete data
- Validating Data
- Persisting Data and Error Handling
- Grouping Data
- Sorting Data
- Filtering Data
- Summary
Starting a New Project
Create a new Silverlight Application (C# or VB.NET).
Enable RIA Services.

Exposing Data from Entity Framework
Add NORTHWND.MDF file to the DomainDataSouceSample.Web\App_Data folder. Of course in a real world example, you’d just have a connection string to an existing database.
Create an Entity Framework model on top of it with the Entity Data Model Wizard.
You will see the created entity model:
Next, we need to write some business logic that controls how to data is retrieved by the Silverlight client. To do that, we add a new DomainService. A DomainService is simply a special kind of WCF service that makes it much easier to query, update, secure and validate your data.
Select which tables you want to display and edit.
This also generates metadata classes (NorthwindDomainService.metadata.cs) for hanging validation attributes on so that you can regenerate the Entity Framework model without losing any customizations.
Consuming Data in the Client with DomainDataSource and xamlDataGrid
WCF RIA Services provides the DomainDataSource control to simplify the interaction between the user interface and data from a domain context. With the DomainDataSource, you can retrieve, display, and edit data using only declarative syntax. You specify the domain context to use with the DomainDataSource, and then call the operations that are available through that domain context.
To use the DomainDataSource control, you must add a reference in the Silverlight project to the System.Windows.Controls.DomainServices assembly. This reference is automatically added when you drag the DomainDataSource from the Toolbox.
To use the xamlDataGrid add a reference to the ComponentWays.Windows.Controls.Data.dll (or better yet, add it to your ToolBox and then drag & drop it from there).
The final result you will have in a Silverlight page containing a DomainDataSource and xamlDataGrid would be something similar to that:
<UserControl x:Class="DomainDataSouceSample.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"
mc:Ignorable="d"
xmlns:cwData="http://schemas.componentways.com/xaml/data"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:domain="clr-namespace:DomainDataSouceSample.Web"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<riaControls:DomainDataSource x:Name="domainDataSource"
AutoLoad="True"
QueryName="GetCustomers">
<riaControls:DomainDataSource.DomainContext>
<domain:NorthwindDomainContext />
</riaControls:DomainDataSource.DomainContext>
<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor PropertyPath="CustomerID" />
</riaControls:DomainDataSource.SortDescriptors>
</riaControls:DomainDataSource>
<cwData:XamlDataGrid x:Name="dataGrid"
HorizontalAlignment="Left"
VerticalAlignment="Top"
AutoGenerateColumns="False"
ItemsSource="{Binding Data, ElementName=domainDataSource}">
<cwData:XamlDataGrid.Columns>
<cwData:XamlDataGridTextColumn Binding="{Binding CustomerID}" Header="Customer ID" />
<cwData:XamlDataGridTextColumn Binding="{Binding CompanyName}" Header="Company Name" />
<cwData:XamlDataGridTextColumn Binding="{Binding Phone}" Header="Phone" />
<cwData:XamlDataGridTextColumn Binding="{Binding PostalCode}" Header="Postal Code" />
<cwData:XamlDataGridDateColumn Binding="{Binding CreationDate}" Header="Creation Date" />
</cwData:XamlDataGrid.Columns>
<cwData:XamlDataGrid.ToolBarSettings>
<cwData:XamlDataGridToolBarSettings CommandButtonsVisibility="All" />
</cwData:XamlDataGrid.ToolBarSettings>
</cwData:XamlDataGrid>
</Grid>
</UserControl>

CRUD: Add, Edit, View, Delete data
One of the ways to add, edit, view, delete data is by using the integrated ToolBar (bottom left in this example).You can launch Add|Edit|View Item Dialog by clicking on the "Add"|"Edit"|"View" button in the xamlDataGrid ToolBar.
Also you can edit cell values in-place with double click on specific cell.

Validating Data
In step 2 when we created NorthwindDomainService domain service, we also created and metadata classes for hanging validation attributes (NorthwindDomainService.metadata.cs). In this file we can attach custom attributes to the properties.
[C#]
// For example, the following marks the Xyz property as a
// required property and specifies the format for valid values:
// [Required]
// [RegularExpression("[A-Z][A-Za-z0-9]*")]
// [StringLength(32)]
// public string Xyz { get; set; }
[VB.NET]
'For example, the following marks the Xyz property as a
' required property and specifies the format for valid values:
' <Required()>
' <RegularExpression("[A-Z][A-Za-z0-9]*")>
' <StringLength(32)>
' Public Property Xyz As String
By default the CompanyName is a required field, so if it is empty we’ll get an error.

Persisting Data and Error Handling
To persist data modifications, call the SubmitChanges method on the DomainDataSource object. To cancel changes, call the RejectChanges method.
To handle errors when submitting data use a SubmitOperation_Callback when you calling the SubmitChanges method and check if there are errors.
The code for this will look like:
[Xaml]
<UserControl
x:Class="DomainDataSouceSample.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:cwData="http://schemas.componentways.com/xaml/data"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:domain="clr-namespace:DomainDataSouceSample.Web"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<riaControls:DomainDataSource x:Name="domainDataSource"
AutoLoad="True"
QueryName="GetCustomers">
<riaControls:DomainDataSource.DomainContext>
<domain:NorthwindDomainContext />
</riaControls:DomainDataSource.DomainContext>
<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor PropertyPath="CustomerID" />
</riaControls:DomainDataSource.SortDescriptors>
</riaControls:DomainDataSource>
<Grid VerticalAlignment="Top" HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<cwData:XamlDataGrid x:Name="dataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Data, ElementName=domainDataSource}">
<cwData:XamlDataGrid.Columns>
<cwData:XamlDataGridTextColumn Binding="{Binding CustomerID}" Header="Customer ID" />
<cwData:XamlDataGridTextColumn Binding="{Binding CompanyName}" Header="Company Name" />
<cwData:XamlDataGridTextColumn Binding="{Binding Phone}" Header="Phone" />
<cwData:XamlDataGridTextColumn Binding="{Binding PostalCode}" Header="Postal Code" />
<cwData:XamlDataGridDateColumn Binding="{Binding CreationDate}" Header="Creation Date" />
</cwData:XamlDataGrid.Columns>
<cwData:XamlDataGrid.ToolBarSettings>
<cwData:XamlDataGridToolBarSettings CommandButtonsVisibility="All" />
</cwData:XamlDataGrid.ToolBarSettings>
</cwData:XamlDataGrid>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,4,0,0">
<Button x:Name="SubmitButton" Content="Submit Changes" Click="SubmitButton_Click" Padding="4" />
<Button x:Name="RejectButton" Content="Reject Changes" Click="RejectButton_Click" Padding="4" />
</StackPanel>
</Grid>
</Grid>
</UserControl>
[C#]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel.DomainServices.Client;
namespace DomainDataSouceSample
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
this.domainDataSource.DomainContext.SubmitChanges(SubmitOperation_Callback, null);
}
private void RejectButton_Click(object sender, RoutedEventArgs e)
{
this.domainDataSource.DomainContext.RejectChanges();
}
private void NorthwindDomainContext_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
bool hasChanges = this.domainDataSource.DomainContext.HasChanges;
this.SubmitButton.IsEnabled = hasChanges;
this.RejectButton.IsEnabled = hasChanges;
}
private void SubmitOperation_Callback(SubmitOperation operation)
{
if (operation.HasError)
{
MessageBox.Show(operation.Error.ToString(), "Submit Error", MessageBoxButton.OK);
operation.MarkErrorAsHandled();
}
}
}
}
[VB.NET]
Imports System.ServiceModel.DomainServices.Client
Partial Public Class MainPage
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
Private Sub SubmitButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.domainDataSource.DomainContext.SubmitChanges(AddressOf SubmitOperation_Callback, Nothing)
End Sub
Private Sub RejectButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.domainDataSource.DomainContext.RejectChanges()
End Sub
Private Sub NorthwindDomainContext_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs)
Dim hasChanges As Boolean = Me.domainDataSource.DomainContext.HasChanges
Me.SubmitButton.IsEnabled = hasChanges
Me.RejectButton.IsEnabled = hasChanges
End Sub
Private Sub SubmitOperation_Callback(ByVal operation As SubmitOperation)
If operation.HasError Then
MessageBox.Show(operation.[Error].ToString(), "Submit Error", MessageBoxButton.OK)
operation.MarkErrorAsHandled()
End If
End Sub
End Class
If we delete some row and trying submitting the changes, we’ll get an error

Grouping Data
The xamlDataGrid provides the GroupDescriptions collection to facilitate grouping the data by property values. In the GroupDescriptions collection, you add GroupDescriptor instances that define the value to use for grouping. You can add as many GroupDescriptor instances as needed.
xmlns:data="clr-namespace:System.Windows.Data;assembly=System.Windows"
…
<cwData:XamlDataGrid x:Name="dataGrid"
VerticalAlignment="Top"
IsReadOnly="True"
AutoGenerateColumns="false"
ItemsSource="{Binding Data, ElementName=domainDataSource}">
<cwData:XamlDataGrid.GroupDescriptions>
<data:PropertyGroupDescription PropertyName="Country" />
</cwData:XamlDataGrid.GroupDescriptions>
…

Sorting Data
Sorting is enabled by default for all xamlDataGrid columns. To sort a column, just click on the header of the respective column. The default sorting logic of the grid in almost all cases is good enough - depending on the type of the column (date, int, float, double, etc) it sorts the column while switching ascending and descending orders.
Filtering Data
You can filter data by using the Filter Dialog functionality. You can launch Filter Dialog clicking on the "Filter" button in the XamlDataGrid ToolBar (bottom left in this example). For this, you need to have toolbar enabled.
The XamlDataGrid supports FilterRow filtering mode. You can set it with FilteringMode property. In this mode you can specify a filter condition on the top of each column of the grid.
<cwData:XamlDataGrid x:Name="dataGrid" FilteringMode="FilterRow" …
In the both cases depending on the specific column type the built-in editors are used: TextBox, CheckBox, DatePicker, ComboBox, AutoCompleteBox. It is all integrated in the XamlDataGrid.
Summary
So that’s all. We created all this with writing almost no code. For more info visit our site - ComponentWays. Discuss in our forum. Follow us on Twitter