MULTIMEDIA

Building LOB Applications : Implementing CRUD Operations in RIA Services

3/19/2011 4:42:53 PM

1. Problem

You need to implement CRUD operations on LOB data that includes complicated business logic.

2. Solution

Take advantage of WCF RIA Services features to support CRUD operations in a customizable way.

3. How It Works

You build on Recipe 7's code, updating the layout a bit, adding a button, and adding the star of the recipe: the DataForm control. This is a very powerful record details editing control that enables all CRUD operations directly. It can be templated and customized from a UI perspective as well. For this recipe, you introduce the control and focus on how to allow edits to happen on the client but control when edits are sent to the server.

4. The Code

You start this recipe by opening the Recipe 8 properties dialog, enabling the WCF RIA Services link for the TestWeb project, saving the project settings, and then recompiling. Then copy the code from Recipe 7 where you databind via XAML and add sorting and paging as your starting point for this recipe.

Adjust the root Layout Grid and position on the filtering TextBox for space to add a Button that commits any edits to the server via WCF RIA Services. Next, add a DataForm control. The DataForm control can bind to either a collection of records or a single record. In this example, you want the DataForm to provide a details view of the selected record in the DataGrid.

To enable this, databind the DataForm.CurrentItem property to the DataGrid's SelectedItem property via Element databinding. Listing 1 has the XAML file code listing.

Listing 1. The Recipe 8 MainPage.Xaml File
<UserControl  x:Class="Ch09_LOBApplications.Recipe9_8.MainPage"
xmlns:dataControls=
"clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:riaControls=
"clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
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:NorthwindData="clr-namespace:TestWeb.DomainService"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="600"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:dataFormToolkit=
"clr-
namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit">
<UserControl.Resources>
<NorthwindData:NorthwindDomainContext x:Key="NorthwindDomainContext" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="34" />
<RowDefinition Height="36" />
<RowDefinition Height="160" />
<RowDefinition Height="*" />



</Grid.RowDefinitions>
<riaControls:DomainDataSource x:Name="CustomersDomainDataSource"
DomainContext="{StaticResource NorthwindDomainContext}"
AutoLoad="True" QueryName="GetCustomersQuery" Grid.RowSpan="4">
<riaControls:DomainDataSource.SortDescriptors >
<riaControls:SortDescriptor PropertyPath="CompanyName"
Direction="Ascending"/>
</riaControls:DomainDataSource.SortDescriptors>
<riaControls:DomainDataSource.FilterDescriptors>
<riaControls:FilterDescriptor PropertyPath="CompanyName"
Operator="StartsWith"
Value="{Binding Text, ElementName=FilterTextBox}" />
</riaControls:DomainDataSource.FilterDescriptors>
</riaControls:DomainDataSource>
<sdk:DataPager PageSize="5" Height="28"
VerticalAlignment="Top" Grid.Row="1" Margin="0,3,0,0"
Source="{Binding Data, ElementName=CustomersDomainDataSource, Mode=TwoWay}" />
<sdk:DataGrid x:Name="CustomersDataGrid" Grid.Row="2" Margin="2"
Height="160" VerticalAlignment="Top" CanUserSortColumns="True"
CanUserReorderColumns="True" CanUserResizeColumns="True"
ItemsSource="{Binding Data,
ElementName=CustomersDomainDataSource, Mode=TwoWay}" />
<StackPanel Margin="0,4,7,0" Orientation="Horizontal" d:LayoutOverrides="Width">
<TextBlock Height="29" x:Name="textBlock1" VerticalAlignment="Top"
LineHeight="13.333" FontSize="13.333" HorizontalAlignment="Left"
Width="355"
Text="Enter The First Few Letters of the Company Name:"
TextAlignment="Center" />
<TextBox x:Name="FilterTextBox" TextWrapping="Wrap" Width="73"
Margin="0,2,0,4"/>
<Button Content="Save To Server" Height="28" HorizontalAlignment="Left"
Margin="30,0,0,0" x:Name="ButtonCommitToServer"
VerticalAlignment="Top"
Width="118" IsEnabled="True" Click="ButtonCommitToServer_Click" />
</StackPanel>
<toolkit:DataForm Margin="2" Grid.Row="3" x:Name="CustomerDataForm"
CurrentItem="{Binding SelectedItem, ElementName=CustomersDataGrid,
Mode=TwoWay}"
AutoCommit="False" AutoEdit="False" Header="Customer Details" />
</Grid>
</UserControl>

Initially, when you drop the DataForm control onto the Grid and databind it to the DataGrid, AutoEdit defaults to True as does the AutoCommit property. Configure both AutoEdit and AutoCommit to false to gain more control over how edits are processed. This also enables the additional button editing UI on the DataForm control as shown in Figure 1.

Figure 1. Final UI for Recipe 8

Clicking the Edit button (the pencil) on the Customer Details DataForm control allows the user to perform CRUD operations. You configure the control explicitly to display all of the buttons in the constructor for MainPage after Initialization. The only other item to cover is the Save to Server button. When you perform edits using the DataForm, they exist on the client in the form of changes to the object representing each database record. Because you disabled AutoCommit, you need to manually send any pending changes, as shown in Listing 2.

Listing 2. Recipe 8 MainPage.Xaml.cs File
using System.Windows;
using System.Windows.Controls;

namespace Ch09_LOBApplications.Recipe9_8
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
CustomerDataForm.CommandButtonsVisibility =
DataFormCommandButtonsVisibility.All;
}

private void ButtonCommitToServer_Click(object sender, RoutedEventArgs e)
{
if (CustomersDomainDataSource.HasChanges &&
!CustomersDomainDataSource.IsBusy)
CustomersDomainDataSource.SubmitChanges();
}
}
}

Other  
  •  Microsoft XNA Game Studio 3.0 : Displaying Images - Resources and Content (part 2) - Adding Resources to a Project
  •  Microsoft XNA Game Studio 3.0 : Displaying Images - Resources and Content (part 1)
  •  iPhone 3D Programming : Blending and Augmented Reality - Rendering Anti-Aliased Lines with Textures
  •  Programming with DirectX : Game Math - Bounding Geometry (part 2) - Bounding Spheres & Bounding Hierarchies
  •  Programming with DirectX : Game Math - Bounding Geometry (part 1) - Bounding Boxes
  •  Programming with DirectX : Game Math - Matrices
  •  iPhone 3D Programming : Anti-Aliasing Tricks with Offscreen FBOs (part 2) - Jittering
  •  iPhone 3D Programming : Anti-Aliasing Tricks with Offscreen FBOs (part 1) - A Super Simple Sample App for Supersampling
  •  Building LOB Applications : Navigating RIA LOB Data
  •  Building LOB Applications : Databinding in XAML
  •  Microsoft XNA Game Studio 3.0 : Program Bugs
  •  Microsoft XNA Game Studio 3.0 : Getting Player Input - Adding Vibration
  •  Microsoft XNA Game Studio 3.0 : Getting Player Input - Using the Keyboard
  •  iPhone 3D Programming : Blending and Augmented Reality - Stencil Alternatives for Older iPhones
  •  iPhone 3D Programming : Blending and Augmented Reality - Poor Man’s Reflection with the Stencil Buffer
  •  Microsoft XNA Game Studio 3.0 : Getting Player Input - Reading a Gamepad
  •  iPhone 3D Programming : Blending and Augmented Reality - Shifting Texture Color with Per-Vertex Color
  •  iPhone 3D Programming : Blending and Augmented Reality - Blending Extensions and Their Uses
  •  iPhone 3D Programming : Blending and Augmented Reality - Blending Caveats
  •  Building LOB Applications : Using Visual Studio 2010 WCF RIA Data Services Tooling
  •  
    Top 10
    Windows Server 2003 : Domain Name System - Command-Line Utilities
    Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 2)
    Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 1)
    Brother MFC-J4510DW - An Innovative All-In-One A3 Printer
    Computer Planet I7 Extreme Gaming PC
    All We Need To Know About Green Computing (Part 4)
    All We Need To Know About Green Computing (Part 3)
    All We Need To Know About Green Computing (Part 2)
    All We Need To Know About Green Computing (Part 1)
    Master Black-White Copying
    Most View
    Epic Moments in Sports (Part 1)
    iPhone 3D Programming : Blending and Augmented Reality - Blending Recipe
    HP X2301 : Micro Thin, Macro Sights
    Advanced ASP.NET : Understanding Caching
    Amateur Astronomy Applications (Part 1) - WorldWide Telescope, Stellarium
    How To Buy…SSD Drives (Part 2)
    Macro Marvel by Peiling Lee
    Under The Surface (Part 1)
    Microsoft .NET : Design Principles and Patterns - Object-Oriented Design (part 1) - Basic OOD Principles
    Hosting a Multi-Tenant Application on Windows Azure : Selecting a Single-Tenant or Multi-Tenant Architecture
    Google Nexus 4 - Features Of A High-End Smartphone For Half The Price
    Developing an SEO-Friendly Website: Content Delivery and Search Spider Control (part 2)
    SQL Server 2008 : Explaining Advanced Query Techniques - Managing Internationalization Considerations
    Frequently Asked Questions About UAC
    Windows Server 2008 : Harnessing the Power and Potential of FIM
    Parallel Programming with Microsoft .Net : Dynamic Task Parallelism - An Example
    Microsoft XNA Game Studio 3.0 : Displaying Images - Using Resources in a Game (part 3) - Sprite Drawing with SpriteBatch
    Windows Server 2003 : Active Directory - Understanding Operations Master Roles
    Windows 7 : Using Windows Defender (part 3) - Using Windows Defender Tools & Troubleshooting Windows Defender
    iOS 6 Beta Review (Part 1)