Subject
How do we create Silverlight application that follows MVVM Web Application 
	Pattern and Performing CRUD operations in Silverlight Data Grid?
 
	What we will be using  
 
	We will be using the ADO.NET Entity and Domain Services for creating Model 
	classes for Employee, Thereby creating the Custom Validation class for 
	validating the class, which will be *.shared.cs. To implement Button 
	operations we will be using ICommand interface to implement the CRUD command 
	operations and thereby for binding with UX.
	 
	A. Creating a Silverlight solution with a RIA Services Link between the 
	Projects
	
		- Create Silverlight Application Project, enter project as 
		MVVM_RIA_ICOMMAND_CUSTOMVALIDATION and solution name as 
		MVVMRIAICOMMANDCUSTOMVALIDATION. Make sure that Enable RIA Service Link 
		check box is selected.
- Create folder in Server application, with name Model.
- Before actually we start working with our example we will create a 
		sample Data base and a table. Data base name will be MVVMDomainData and 
		Table name is Employee. I am using SQL Server 2008 Express. Now we have 
		environment ready for the development.
 
	B. Creating a ADO.NET Entity Model for Employee table             
	
		- Add a new ADO.NET Entity Data Model item to the model folder in the 
		server project. Name it as EmployeeModel. Click on Add
- Select Generate from database and click on Next.
- Add new connection, as we create in ADO.NET. Select the database 
		that we created. And click on Next. Select the check box "save entity 
		connection string in We.Config as".
- The Dialog box comes up with all the Tables, View and SP that we 
		have created in our DB, MVVMDomainData. Select the table that we 
		created, Employee. And click on Finish.
- Let us look at the class that generated for us. This has Context and 
		Entities. Let us see the Entities where we have to understand what 
		exactly it is. The class inherits from the EntityObject. EntityObject 
		class inherits from the StructuralObject. StructuralObject implements 
		INotifyPropertyChanging, INotifyPropertyChanged interfaces. Out of all, 
		we need to understand purpose of the following methods. These methods 
		will track the change make to the data and in UX and keep update the 
		Context object so that the changes reflects in all the places where the 
		context object is being shared.
 
 protected virtual void OnPropertyChanged(string property);
 protected virtual void OnPropertyChanging(string property);
 protected virtual void ReportPropertyChanged(string property);
 protected virtual void ReportPropertyChanging(string property);
 
 Going back to the generated entityonject which will have a Factory 
		method that can used as to create new entity object and Properties for 
		the each filed in the data base.
 
 /// <summary>
 /// No 
		Metadata Documentation available.
 /// </summary>
 [EdmScalarPropertyAttribute(EntityKeyProperty=false, 
		IsNullable=false)]
 [DataMemberAttribute()]
 public global::System.String FirstName
 {
 get
 {
 return _FirstName;
 }
 set
 {
 OnFirstNameChanging(value);
 ReportPropertyChanging("FirstName");
 _FirstName = StructuralObject.SetValidValue(value, false);
 ReportPropertyChanged("FirstName");
 OnFirstNameChanged();
 }
 }
 private global::System.String _FirstName;
 partial void OnFirstNameChanging(global::System.String value);
 partial void OnFirstNameChanged();
 
	
		- EntityKeyProperty --> tell that it is autogenerated or 
		not.
- IsNullable --> tell us that is allows null in the DB or Not.
- DataMemberAttribute --> Each is field is decorated and mapped to DB 
		table field.
- ReportPropertyChanged("FirstName"); OnFirstNameChanged(); 
		ReportPropertyChanged("FirstName"); OnFirstNameChanged(); are used for 
		tracking the changes happening to the field value.
 
	C. Creating Domain Service class of the Model
	
		- Right on the Model folder and click on add new item. Select the 
		Visual C# on the left side and select Domain Service class on the left 
		side. Name the class as EmployeeDomain.cs, and click add. 
- Build the Solution (F6).
- The Model that we created will automatically picked up by the Visual 
		Studio. Show all the tables that we have selected during the model 
		creation. Select the Entities and Enable Editing Check boxes. By 
		selecting Enable editing check box will generated the methods required 
		for Delete, Update and Insert. Also select Generate associated class for 
		metadata, which we will see later part of the example. And click On
- Build the solution
- Let us see the generated domain class. 
		[EnableClientAccess()]
 public class EmployeeDomain : LinqToEntitiesDomainService<MVVMDomainDataEntities>
 {
 public IQueryable<Employee> 
		GetEmployees()
 {
 return this.ObjectContext.Employees;
 }
 public void InsertEmployee(Employee employee)
 {
 if ((employee.EntityState 
		!= EntityState.Detached))
 {
 this.ObjectContext.ObjectStateManager.ChangeObjectState(employee, EntityState.Added);
 }
 else
 {
 this.ObjectContext.Employees.AddObject(employee);
 }
 }
 public void UpdateEmployee(Employee currentEmployee)
 {
 this.ObjectContext.Employees.AttachAsModified(currentEmployee,this.ChangeSet.GetOriginal(currentEmployee));
 }
 public void DeleteEmployee(Employee employee)
 {
 if ((employee.EntityState 
		== EntityState.Detached))
 {
 this.ObjectContext.Employees.Attach(employee);
 }
 this.ObjectContext.Employees.DeleteObject(employee);
 }
 }
 
 
	
		- EnableClientAccess --> Marks Domain Service class as 
		accessible to clients. We must apply theEnableClientAccessAttribute 
		attribute to a domain service to make it accessible to the client 
		application. A DomainContext class is generated for each domain service 
		that is marked with theEnableClientAccessAttribute attribute. When you 
		create a domain service by using the Add New Domain Service Class 
		wizard, the wizard contains a check box called Enable client access that 
		is selected by default. The EnableClientAccessAttribute is applied to 
		the domain service when this check box is selected.
- GetEmployees() --> is of type IQueryable<Employee> which allows to 
		apply LINQ queries in the client.
- Also we can see the methods for CRUD.
 
	D. Create View Model
	
		- Create ViewModel folder in Client Project. And then add 
		EmployeeViewModel.cs class.
- Add reference System.ServiceModel.DomainServices.Client dll.
- Add following using statements 
		using System.ComponentModel; --> we 
		will be sing INotifyPropertyChanged interface
 using System.ServiceModel.DomainServices.Client;
 using MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.Web.Model; 
		-- > Through RIA services the link will be available to Mode in the 
		Server project
 
- Implement the INotifyPropertyChanged interface in the view model 
		class. With that we will have following code in the Employee View Model 
		class 
		public event PropertyChangedEventHandler PropertyChanged;
 private void RaisePropertyChanged 
		(string propertyName)
 {
 if (PropertyChanged 
		!= null)
 {
 PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
 }
 }
 
 
- Declare a class scope variable for EmployeeDomain, is 
		located in the Generated_Code folder. This is hidden folder in the 
		client project. EmployeeDomain class provides access to its instance 
		members that are generated in the EmployeeDomainService class. 
		private EmployeeDomain _employeeDomainContext 
		=  new EmployeeDomain();
 public EmployeeViewModel()
 {
 _employeeDomainContext.Load<Employee>(_employeeDomainContext.GetEmployeesQuery());
 }
 
 
- What Next? remember anything that we need to bind to 
		the View from View Model should be a property in the corresponding View 
		Model class. So, first thing we need to bind is all employees to the 
		grid. So this, Employees, property will the data context for the view. 
		public EntitySet<Employee> 
		Employees
 {
 get
 {
 return _employeeDomainContext.Employees;
 }
 }
 
 
- 
		
		Provide a property for the Selected Employee Recode in the View Model so 
		that, this will help in pointing to the selected in the Grid.
 
 private Employee _employee = null;
 public Employee SelectedEmployee
 {
 get
 {
 return _employee;
 }
 set
 {
 _employee = value;
 RaisePropertyChanged("SelectedEmployee");
 }
 }
 
	E. Create View
	 
	With the all the above details let us create a view and see the code is 
	status. What we will do is we will create a View folder with Employee 
	DataGrid added to it. And then add this to the main page.
	
		- Create a folder 'View' in the Client Application and add a new 
		Silverlight User Control to It. Name it as EmployeeGrid.xaml
- Add Referance of the View Mode to the User Controls and then add the 
		DataGrid to the root Grid. 
		<UserControl x:Class="MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.View.EmployeeGrid"
 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:ViewModel="clr-namespace:MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.ViewModel"
 mc:Ignorable="d"
 d:DesignHeight="300" d:DesignWidth="400"xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
 <Grid x:Name="LayoutRoot" Background="White">
 <sdk:DataGrid Name="employeeGridView"/>
 </Grid>
 </UserControl>
 
 
- Go to main page and add View Reference and then add 
		the Emplyee Grid view user control that we created. 
		<UserControl x:Class="MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.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:Views="clr-namespace:MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.View"
 mc:Ignorable="d"
 d:DesignHeight="300" d:DesignWidth="400">
 <Grid x:Name="LayoutRoot" Background="White">
 <Views:EmployeeGrid x:Name="employeeGrid" 
		/>
 </Grid>
 </UserControl>
 
 
 
- Now we will bind to the Employee Grid with the 
		Employee View Model. Bind the Property "Employees" that we created in 
		Employee View Model, in the View using ItemSource.
 
 <UserControl x:Class="MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.View.EmployeeGrid"
 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:ViewModel="clr-namespace:MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.ViewModel"
 mc:Ignorable="d"
 d:DesignHeight="300" d:DesignWidth="400"xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
 <Grid x:Name="LayoutRoot" Background="White">
 <sdk:DataGrid Name="employeeGridView" ItemsSource="{Binding Employees}"/>
 </Grid>
 </UserControl>
 
 
- Coming back to the MainPage.xaml, Add the following 
		code to the MainPage.xaml.cs. 
		employeeGrid.DataContext =new MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.ViewModel.EmployeeViewModel();
 
 
- That's it, Build and run your application. I know 
		that you will get many questions now. Let us some of them.
 
	
	
	
		Question 
	
	
		
			- How do we get the fields displayed in a specific order?
 
 The Answer is "EmployeeDomain.metadata.cs" which is generated along 
			with the Domain Service class.
 
 Set the [[Display(Order=0)] attribute to the fields. So, with this 
			our EmployeeDomain.metadata.cs class will become as follows. Build 
			and Run the application.
 
 public partial class Employee
 {
 internal sealed class EmployeeMetadata
 {
 private EmployeeMetadata()
 {
 }
 [Display(Order = 3)]
 public string Email 
			{ get; set; 
			}
 [Display(Order = 2)]
 public string FirstName 
			{ get; set; 
			}
 public DateTime HireDate 
			{ get; set; 
			}
 [Display(Order=0)]
 public int ID 
			{ get; set; 
			}
 [Display(Order = 1)]
 public string LastName 
			{ get; set; 
			}
 [Display(Order = 4)]
 public string Phone 
			{ get; set; 
			}
 [Display(Order = 5)]
 public string SSN 
			{ get; set; 
			}
 [Display(Order = 6)]
 public string URL 
			{ get; set; 
			}
 }
 }
 
- 
			
			How do make the ID 
			filed non-editable, since it is Auto generated primary key.
 
 Answer is The Answer is "EmployeeDomain.metadata.cs" which is 
			generated along with the Domain Service class.  Set the 
			[Editable(false)] attribute to any field that is non-editable. Then 
			double click on the ID column at run time it will not allow you edit 
			it.
 
 [Editable (false)]
 [Display (Order=0)]
 public int ID {get; set ;}
 
- 
			
			
			
			
			
			How do we Add new 
			Row it the Grid?
 
 When we want to add new Row to the Grid it is nothing but adding a 
			new employee record to our EmployeeDomainContext. Now what we need 
			to do is Add a new button, called 'Add New' to the Employee Grid 
			user control.
 
 On click of the button we need to call come property in the Employee 
			View Model to create a new Employee object and then add to the 
			EmployeeDomainContext object. And then somehow we need to tell the 
			UX that EmployeeDomainContext has been changed and the new added 
			empty now should appear.
 
 All this is taken care by the ICommand and INotifyPropertyChanged 
			interfaces. Follow the steps.
 
				- Add class file called 'EmplyeeInsertCommand' 
				to ViewModel and Implement the ICommand Interface; ICommand is 
				available in System.Windows.Input namespace. Add the following 
				code to it.
 
					private EmployeeViewModel _employeeViewModel; 
					public EmployeeViewModel (EmployeeViewModel employeeViewModel) 
					{ 
					    this._employeeViewModel 
					= employeeViewModel; 
					} 
					public bool CanExecute(object parameter) 
					{ 
					    return true; 
					} 
					public event EventHandler CanExecuteChanged; 
					public void Execute(object parameter) 
					{ 
					    _employeeViewModel.Insert(); 
					} 
- We need to Add the following code to the 'Insert' method in the EmployeeViewModel.cs
 
					public void Insert() 
					{ 
					    Employee employee = new Employee(); 
					    //employee.ID 
					= 0; 
					   
					 _employeeDomainContext.Employees.Add(employee); 
					    RaisePropertyChanged(ed("Employees"); 
					} What happens here is when we add new Employee 
				object to the EmployeeDomainContext, RaisePropertyChanged even 
				will be fired and saying whichever element is binded to the 
				Employees property needs to updated. And will be updated. 
- Declare a public property, InsertCommand, to 
				the EmployeeViewModel.cs that return EmplyeeInsertCommand 
 
					public ICommand InsertCommand 
					
					
					{ 
					
					    get 
					
					
					
					    { 
					
					
					
					
					
					
					       return new InsertCommand(this); 
					
					    } 
					
					
					
					} 
- Bind this 'InsertCommand' property to the 'Add New'. Build the application and Run. Also make sure that 
				DataGrid SelectedItem is binded to SelectedEmployee
 
					<UserControlx:Class="MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.View.EmployeeGrid" 
					
					
					    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:ViewModel="clr-namespace:MVVM_RIA_ICOMMAND_CUSTOMVALIDATION.ViewModel" 
					
					
					    mc:Ignorable="d" 
					
					
					    d:DesignHeight="300" d:DesignWidth="400"xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> 
					
					
					    <Grid x:Name="LayoutRoot" Background="White" Grid.Row="0"> 
					
					
					     
					   <sdk:DataGrid Name="employeeGridView" ItemsSource="{BindingEmployees}" 
					
					
					                      SelectedItem="{Binding SelectedEmployee,Mode=TwoWay}" /> 
					
					
					
					
					                   <Button Content="Insert" Name="btnInsert" Grid.Row="1" 
					
					
					
					
					
					
					                    Command="{Binding InsertCommand}" Margin="12,7,247,164" Width="140"/> 
					
					
					
					
					
					
					
					    </Grid> 
					
					
					
					
					
					
					</UserControl>
 
 
 
 
- How do we save the newly add row to the Grid?
 
				
					- In EmployeeViewMode class add a method called Save 
 
					public void Save() 
					{ 
					    if (_employeeDomainContext.HasChanges) 
					    { 
					
					        _employeeDomainContext.SubmitChanges(); 
					
					        RaisePropertyChanged("Employees"); 
					    } 
					} 
- Add new class item to ViewModel folder 
					with the EmployeeUpdateCommand. Add the following code. 
					Similar how we did it for EmplyeeInsertCommand. 
 
						private EmployeeViewModel _employeeViewModel; 
						public EmployeeUpdateCommand(EmployeeViewModel employeeViewModel) 
						{ 
						    this._employeeViewModel 
						= employeeViewModel; 
						} 
						public bool CanExecute(object parameter) 
						{ 
						    return true; 
						} 
						public event EventHandler CanExecuteChanged; 
						public void Execute(object parameter) 
						{ 
						   
						 _employeeViewModel.Save(); 
						}  
- Add new property called SameCommand to 
					the EmployeeViewModel class. This will bind to the Save 
					button in the Employee Grid View. 
 
						public ICommand SaveCommand 
						{ 
						
						
						    get 
						
						
						
						    { 
						
						
						
						
						
						
						
						
						        return new EmployeeUpdateCommand (this); 
						
						
						
						    } 
						
						
						
						} 
- Add a Save button to Employee Grid View 
					and bind SaveCommand property to it. 
 
						<Grid x:Name="LayoutRoot" Background="White"> 
						
						
						
						        <Grid.RowDefinitions > 
						
						
						
						            <RowDefinition /> 
						
						
						
						            <RowDefinition /> 
						
						
						
						        </Grid.RowDefinitions> 
						
						
						<sdk:DataGrid Name="employeeGridView" ItemsSource="{BindingEmployees}" Grid.Row="0"/> 
						
						
						
						          <Button Content="Add 
						new" Name="btnInsert" Grid.Row="1" 
						
						
						Command="{Binding InsertCommand}" Margin="46,60,214,60" Width="140"  Height="30"  /> 
						
						
						
						        <Button Content="Save" Name="btnSave" Grid.Row="1" 
						
						
						Command="{Binding SaveCommand}" Margin="225,60,35,60" Width="140"Height="30"/> 
						
						
						</Grid>  
- Build and Run the application. Take a 
					chance to add and save the new row.
 
 
 
- How to validate the data when we add new row?
			By default when we bind to the DataGrid, all the SQL Table field 
			attributes are applied to the grid. But Still if you want to enforce 
			the same. Add the following attribute in the 
			EmployeeDomain.metadata.cs class wherever relevant.   
				- 
				
				DataTypeAttribute
- RangeAttribute
- 
				
					RegularExpressionAttribute 
- 
				
					RequiredAttribute 
- 
				
					StringLengthAttribute 
  
 
- How do we add custom validations to validate the data? Like 
			SSN, Phone and email validation. 
 
 The answer is by using RegularExpressionAttribute to the fields in 
			theEmployeeDomain.metadata.cs class
				
 For example, SSN format: Valid format is XXX-XX-XXXX.
 
				  
				[RegularExpression(@"^\d{3}-\d{2}-\d{4}$", 
				ErrorMessage = "Valid 
				SSN format is 123-12-1234")] 
				[Display(Order 
				= 5)] 
				public string SSN 
				{ get; set; 
				}  
Similarly we can apply any validation format. Run the 
		application edit and click on Save. Check you DB table. 
	
	
	
	
	
	
		 
	
		Now you can try with the Delete Command