Geeks With Blogs
Dejan Jakovic ComponentWays
| Home |

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).

New Silverlight Project

Enable RIA Services.

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.

Northwind Database

Create an Entity Framework model on top of it with the Entity Data Model Wizard.

Entity Framework model

Entity Data Model Wizard

Connection String

Database objects

You will see the created entity model:

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.

DomainService

Select which tables you want to display and edit.

DomainService

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).

Add reference to ComponentWays.Windows.Controls.Data.dll

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>

ComponentWays Silverlight DataGrid - xamlDataGrid

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.

ComponentWays Silverlight DataGrid - Add New Item Dialog

ComponentWays Silverlight DataGrid - Edit Item Dialog

Also you can edit cell values in-place with double click on specific cell.

ComponentWays Silverlight DataGrid - Inline Editors

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.

ComponentWays Silverlight DataGrid - Data Validation

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


ComponentWays Silverlight DataGrid - Persisting Data

If we delete some row and trying submitting the changes, we’ll get an error

ComponentWays Silverlight DataGrid - Error Handling

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>


ComponentWays Silverlight DataGrid - Grouping

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.

ComponentWays Silverlight DataGrid - Filter Dialog

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"


ComponentWays Silverlight DataGrid - Filters

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

Posted on Saturday, October 2, 2010 9:23 AM | Back to top


Comments on this post: RIA Services (DomainDataSource) and ComponentWays Silverlight DataGrid (xamlDataGrid) - Add, Edit, Delete, Group, Sort, Filter data

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Dejan Jakovic | Powered by: GeeksWithBlogs.net