Data Driven Application Development using WCF and Silverlight 3.0 User Controls
A few days ago, I was discussing with one of my techie friends about Silverlight 3.0 user controls and loading these controls on demand for performing DB operations like insert, update and delete. During the discussion, he also insisted that these operations should be available based upon user authorization. I liked the idea and started working on it.
In this article we will see how user controls can be developed and how we can display them at runtime. Those who are using Silverlight 3.0 for DB operations know that we require a WCF service which will make calls to the database.
In this article, I have used Silverlight user controls. The reason behind it is that DML operations needs to be made available based upon authorization and user controls can be displayed on request.
Task 1: Creating WCF Service
Step 1: Open VS2008, and create a blank solution, name it as ‘SILV3_PerformingDML’. To this solution add a new WCF Web Project template and name this as ‘WCF_DMLService’ as shown below:
Step 2: Write following ServiceContract, OperationContact and DataContract. ServiceContract defines methods for performing DML operations. These OperationContact accepts DataContract class as input parameters.
C#
using System.Runtime.Serialization;
using System.ServiceModel;
namespace WCF_DMLService
{
[ServiceContract]
public interface IDMLService
{
[OperationContract]
int CreateEmployee(clsEmployee objEmp);
[OperationContract]
int UpdateEmployee(clsEmployee objEmp);
[OperationContract]
int DeleteEmployeeByEmpNo(clsEmployee objEmp);
[OperationContract]
clsEmployee[] GetAllEmployee();
}
[DataContract]
public class clsEmployee
{
[DataMember]
public int EmpNo { get; set; }
[DataMember]
public string EmpName { get; set; }
[DataMember]
public int Salary { get; set; }
[DataMember]
public int DeptNo { get; set; }
}
}
VB.NET
Imports System.Runtime.Serialization
Imports System.ServiceModel
Namespace WCF_DMLService
<ServiceContract> _
Public Interface IDMLService
<OperationContract> _
Function CreateEmployee(ByVal objEmp As clsEmployee) As Integer
<OperationContract> _
Function UpdateEmployee(ByVal objEmp As clsEmployee) As Integer
<OperationContract> _
Function DeleteEmployeeByEmpNo(ByVal objEmp As clsEmployee) As Integer
<OperationContract> _
Function GetAllEmployee() As clsEmployee()
End Interface
<DataContract> _
Public Class clsEmployee
Private privateEmpNo As Integer
<DataMember> _
Public Property EmpNo() As Integer
Get
Return privateEmpNo
End Get
Set(ByVal value As Integer)
privateEmpNo = value
End Set
End Property
Private privateEmpName As String
<DataMember> _
Public Property EmpName() As String
Get
Return privateEmpName
End Get
Set(ByVal value As String)
privateEmpName = value
End Set
End Property
Private privateSalary As Integer
<DataMember> _
Public Property Salary() As Integer
Get
Return privateSalary
End Get
Set(ByVal value As Integer)
privateSalary = value
End Set
End Property
Private privateDeptNo As Integer
<DataMember> _
Public Property DeptNo() As Integer
Get
Return privateDeptNo
End Get
Set(ByVal value As Integer)
privateDeptNo = value
End Set
End Property
End Class
End Namespace
Step 3: Implement the service contract interface in the service class ‘CDMLService’.
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace WCF_DMLService
{
public class CDMLService : IDMLService
{
SqlConnection Conn;
SqlCommand Cmd;
#region IDMLService Members
public int CreateEmployee(clsEmployee objEmp)
{
Conn = new SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI");
Cmd = new SqlCommand();
Conn.Open();
Cmd.Connection = Conn;
Cmd.CommandText = "Insert into Employee Values(@EmpNo,@EmpName,@Salary,@DeptNo)";
Cmd.Parameters.AddWithValue("@EmpNo", objEmp.EmpNo);
Cmd.Parameters.AddWithValue("@EmpName", objEmp.EmpName);
Cmd.Parameters.AddWithValue("@Salary", objEmp.Salary);
Cmd.Parameters.AddWithValue("@DeptNo", objEmp.DeptNo);
int Inserted = Cmd.ExecuteNonQuery();
if (Inserted > 0)
{
Inserted = 1;
}
else
{
Inserted = 0;
}
Conn.Close();
Cmd.Dispose();
Conn.Dispose();
return Inserted;
}
public int DeleteEmployeeByEmpNo(clsEmployee objEmp)
{
Conn = new SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI");
Cmd = new SqlCommand();
Conn.Open();
Cmd.Connection = Conn;
Cmd.CommandText = "Delete from Employee where EmpNo=@EmpNo";
Cmd.Parameters.AddWithValue("@EmpNo", objEmp.EmpNo);
int Deleted = Cmd.ExecuteNonQuery();
if (Deleted > 0)
{
Deleted = 1;
}
else
{
Deleted = 0;
}
Conn.Close();
Cmd.Dispose();
Conn.Dispose();
return Deleted;
}
public clsEmployee[] GetAllEmployee()
{
Conn = new SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI");
Cmd = new SqlCommand();
Conn.Open();
Cmd.Connection = Conn;
Cmd.CommandText = "Select * from Employee";
SqlDataReader Reader = Cmd.ExecuteReader();
int i = 0;
DataTable DtEmp = new DataTable();
DtEmp.Load(Reader);
clsEmployee[] arrEmp = new clsEmployee[DtEmp.Rows.Count];
foreach (DataRow Dr in DtEmp.Rows)
{
arrEmp[i] = new clsEmployee();
arrEmp[i].EmpNo = Convert.ToInt32(Dr["EmpNo"]);
arrEmp[i].EmpName = Dr["EmpName"].ToString();
arrEmp[i].DeptNo = Convert.ToInt32(Dr["DeptNo"]);
arrEmp[i].Salary = Convert.ToInt32(Dr["Salary"]);
i = i + 1;
}
Conn.Close();
Cmd.Dispose();
Conn.Dispose();
return arrEmp;
}
#endregion
public int UpdateEmployee(clsEmployee objEmp)
{
Conn = new SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI");
Cmd = new SqlCommand();
Conn.Open();
Cmd.Connection = Conn;
Cmd.CommandText = "Update Employee Set EmpName=@EmpName,Salary=@Salary,DeptNo=@DeptNo where EmpNo=@EmpNo";
Cmd.Parameters.AddWithValue("@EmpNo", objEmp.EmpNo);
Cmd.Parameters.AddWithValue("@EmpName", objEmp.EmpName);
Cmd.Parameters.AddWithValue("@Salary", objEmp.Salary);
Cmd.Parameters.AddWithValue("@DeptNo", objEmp.DeptNo);
int Updated = Cmd.ExecuteNonQuery();
if (Updated > 0)
{
Updated = 1;
}
else
{
Updated = 0;
}
Conn.Close();
Cmd.Dispose();
Conn.Dispose();
return Updated;
}
}
}
VB.NET
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.Text
Imports System.Data
Imports System.Data.SqlClient
Namespace WCF_DMLService
Public Class CDMLService
Inherits IDMLService
Private Conn As SqlConnection
Private Cmd As SqlCommand
#Region "IDMLService Members"
Public Function CreateEmployee(ByVal objEmp As clsEmployee) As Integer
Conn = New SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI")
Cmd = New SqlCommand()
Conn.Open()
Cmd.Connection = Conn
Cmd.CommandText = "Insert into Employee Values(@EmpNo,@EmpName,@Salary,@DeptNo)"
Cmd.Parameters.AddWithValue("@EmpNo", objEmp.EmpNo)
Cmd.Parameters.AddWithValue("@EmpName", objEmp.EmpName)
Cmd.Parameters.AddWithValue("@Salary", objEmp.Salary)
Cmd.Parameters.AddWithValue("@DeptNo", objEmp.DeptNo)
Dim Inserted As Integer = Cmd.ExecuteNonQuery()
If Inserted > 0 Then
Inserted = 1
Else
Inserted = 0
End If
Conn.Close()
Cmd.Dispose()
Conn.Dispose()
Return Inserted
End Function
Public Function DeleteEmployeeByEmpNo(ByVal objEmp As clsEmployee) As Integer
Conn = New SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI")
Cmd = New SqlCommand()
Conn.Open()
Cmd.Connection = Conn
Cmd.CommandText = "Delete from Employee where EmpNo=@EmpNo"
Cmd.Parameters.AddWithValue("@EmpNo", objEmp.EmpNo)
Dim Deleted As Integer = Cmd.ExecuteNonQuery()
If Deleted > 0 Then
Deleted = 1
Else
Deleted = 0
End If
Conn.Close()
Cmd.Dispose()
Conn.Dispose()
Return Deleted
End Function
Public Function GetAllEmployee() As clsEmployee()
Conn = New SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI")
Cmd = New SqlCommand()
Conn.Open()
Cmd.Connection = Conn
Cmd.CommandText = "Select * from Employee"
Dim Reader As SqlDataReader = Cmd.ExecuteReader()
Dim i As Integer = 0
Dim DtEmp As New DataTable()
DtEmp.Load(Reader)
Dim arrEmp(DtEmp.Rows.Count - 1) As clsEmployee
For Each Dr As DataRow In DtEmp.Rows
arrEmp(i) = New clsEmployee()
arrEmp(i).EmpNo = Convert.ToInt32(Dr("EmpNo"))
arrEmp(i).EmpName = Dr("EmpName").ToString()
arrEmp(i).DeptNo = Convert.ToInt32(Dr("DeptNo"))
arrEmp(i).Salary = Convert.ToInt32(Dr("Salary"))
i = i + 1
Next Dr
Conn.Close()
Cmd.Dispose()
Conn.Dispose()
Return arrEmp
End Function
#End Region
Public Function UpdateEmployee(ByVal objEmp As clsEmployee) As Integer
Conn = New SqlConnection("Data Source=.;Initial Catalog=Company;Integrated Security=SSPI")
Cmd = New SqlCommand()
Conn.Open()
Cmd.Connection = Conn
Cmd.CommandText = "Update Employee Set EmpName=@EmpName,Salary=@Salary,DeptNo=@DeptNo where EmpNo=@EmpNo"
Cmd.Parameters.AddWithValue("@EmpNo", objEmp.EmpNo)
Cmd.Parameters.AddWithValue("@EmpName", objEmp.EmpName)
Cmd.Parameters.AddWithValue("@Salary", objEmp.Salary)
Cmd.Parameters.AddWithValue("@DeptNo", objEmp.DeptNo)
Dim Updated As Integer = Cmd.ExecuteNonQuery()
If Updated > 0 Then
Updated = 1
Else
Updated = 0
End If
Conn.Close()
Cmd.Dispose()
Conn.Dispose()
Return Updated
End Function
Step 4: Right click on the ‘CDMLService.svc’ and select ‘View Markup’ and write the following:
<%@ ServiceHost Language="C#" Debug="true" Service="WCF_DMLService.CDMLService"
CodeBehind="CDMLService.svc.cs" %>
Step 5: Make modifications in the ‘Web.Config’ file as shown below:
<system.serviceModel>
<services>
<service behaviorConfiguration="ServBehave" name="WCF_DMLService.CDMLService">
<endpoint address="" binding="basicHttpBinding" contract="WCF_DMLService.IDMLService">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServBehave">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Step 6: Build the service and publish it on the IIS available on your machine or probably on the server to which you are having access.
Once you publish it on web server, browse to the Active Directory and browse the ‘CDMLService.svc’ file. You should get the service page.
Task 2: Creating Silverlight 3.0 Client application
In this task we will create a Silverlight 3.0 application. This will act as a consumer of WCF service
Step 1: Right-click on the solution and add a new Silverlight project, name this as ‘SILV3-DMLClientApplication’. You will get ‘MainPage.xaml’ > rename this as ‘HomePage.xaml’
Step 2: Open App.Xaml.cs file and change the ‘Application_Startup’ method as shown below:
C#
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new HomePage();
}
VB.NET
Private Sub Application_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
Me.RootVisual = New HomePage()
End Sub
Step 3: Open HomePage.xaml and write the following xaml code:
<UserControl xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" x:Class="SILV3_DMLClientApplication.HomePage"
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" d:DesignWidth="700" d:DesignHeight="600">
<Grid x:Name="LayoutRoot" Height="590" Width="690">
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="590"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel
Orientation="Horizontal"
Grid.Row="0" Height="98"
Background="LightGray" Width="688"
Margin="1,1,2,1">
<TextBlock Width="60"></TextBlock>
<Button x:Name="btnLoadInsert" Height="80" Width="80" Content="Get Insert" Click="btnLoadInsert_Click"></Button>
<TextBlock Width="50"></TextBlock>
<Button x:Name="btnLoadUpdate" Height="80" Width="80" Content="Get Update" Click="btnLoadUpdate_Click"></Button>
<TextBlock Width="50"></TextBlock>
<Button x:Name="btnLoadDelete" Height="80" Width="80" Content="Get Delete" Click="btnLoadDelete_Click"></Button>
<TextBlock Width="50"></TextBlock>
<Button x:Name="btnLoadGetAll" Height="80" Width="80" Content="Get All" Click="btnLoadGetAll_Click"></Button>
<TextBlock Width="50"></TextBlock>
<Button x:Name="btnClearAll" Height="80" Width="80" Content="Clear All" Click="btnClearAll_Click"></Button>
</StackPanel>
<Canvas x:Name="canvMain" Grid.Row="1" Height="590" Width="688" Background="LightCyan">
</Canvas>
</Grid>
</UserControl>
Note: Please ignore Click event at this moment we will use it afterwards
Step 4: In the Silverlight project add the service reference to the WCF service published on IIS.
Step 5: In the Silverlight project > right click > select Add New Item > select Silverlight user control and name it as ‘InsertPage.xaml’
Add the following Xaml code to it:
<UserControl x:Class="SILV3_DMLClientApplication.InsertPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="400">
<Grid x:Name="LayoutRoot" Background="LightCyan"
Width="400" Height="400" >
<Grid.RowDefinitions>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="80"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="EmpNo"></TextBlock>
<TextBlock Grid.Column="0" Grid.Row="1" Text="EmpName"></TextBlock>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Salary"></TextBlock>
<TextBlock Grid.Column="0" Grid.Row="3" Text="DeptNo"></TextBlock>
<TextBox x:Name="txtEmpNo" Grid.Column="1" Grid.Row="0"></TextBox>
<TextBox x:Name="txtEmpName" Grid.Column="1" Grid.Row="1"></TextBox>
<TextBox x:Name="txtSalary" Grid.Column="1" Grid.Row="2"></TextBox>
<TextBox x:Name="txtDeptNo" Grid.Column="1" Grid.Row="3"></TextBox>
<Button x:Name="btnCancel" Grid.Column="0" Grid.Row="4"
Content="Cancel" Click="btnCancel_Click"></Button>
<Button x:Name="btnInsert" Grid.Column="1" Grid.Row="4"
Content="Save" Click="btnInsert_Click"></Button>
</Grid>
</UserControl>
The above user control will be used for performing insert operation.
Step 6: In the InsertPage.xaml.cs write the following code as shown below. This code will call the Insert method from the WCF service:
C#
namespace SILV3_DMLClientApplication
{
public partial class InsertPage : UserControl
{
MyRef.DMLServiceClient Proxy;
MyRef.clsEmployee objEmp;
public InsertPage()
{
InitializeComponent();
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
foreach (UIElement Element in LayoutRoot.Children)
{
if (Element.GetType() == typeof(System.Windows.Controls.TextBox))
{
((TextBox)Element).Text = "";
}
}
}
private void btnInsert_Click(object sender, RoutedEventArgs e)
{
Proxy = new SILV3_DMLClientApplication.MyRef.DMLServiceClient();
objEmp = new SILV3_DMLClientApplication.MyRef.clsEmployee();
objEmp.EmpNo = Convert.ToInt32(txtEmpNo.Text);
objEmp.EmpName = txtEmpName.Text;
objEmp.Salary = Convert.ToInt32(txtSalary.Text);
objEmp.DeptNo = Convert.ToInt32(txtDeptNo.Text);
Proxy.CreateEmployeeCompleted += new EventHandler<SILV3_DMLClientApplication.MyRef.CreateEmployeeCompletedEventArgs>(Proxy_CreateEmployeeCompleted);
Proxy.CreateEmployeeAsync(objEmp);
}
void Proxy_CreateEmployeeCompleted(object sender, SILV3_DMLClientApplication.MyRef.CreateEmployeeCompletedEventArgs e)
{
if ((int?)e.Result != null)
{
if (e.Result == 1)
{
HtmlPage.Window.Alert("Record Inserted Successfully");
}
}
}
}
}
VB.NET
Namespace SILV3_DMLClientApplication
Partial Public Class InsertPage
Inherits UserControl
Private Proxy As MyRef.DMLServiceClient
Private objEmp As MyRef.clsEmployee
Public Sub New()
InitializeComponent()
End Sub
Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
For Each Element As UIElement In LayoutRoot.Children
If Element.GetType() Is GetType(System.Windows.Controls.TextBox) Then
CType(Element, TextBox).Text = ""
End If
Next Element
End Sub
Private Sub btnInsert_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Proxy = New SILV3_DMLClientApplication.MyRef.DMLServiceClient()
objEmp = New SILV3_DMLClientApplication.MyRef.clsEmployee()
objEmp.EmpNo = Convert.ToInt32(txtEmpNo.Text)
objEmp.EmpName = txtEmpName.Text
objEmp.Salary = Convert.ToInt32(txtSalary.Text)
objEmp.DeptNo = Convert.ToInt32(txtDeptNo.Text)
AddHandler Proxy.CreateEmployeeCompleted, AddressOf Proxy_CreateEmployeeCompleted
Proxy.CreateEmployeeAsync(objEmp)
End Sub
Private Sub Proxy_CreateEmployeeCompleted(ByVal sender As Object, ByVal e As SILV3_DMLClientApplication.MyRef.CreateEmployeeCompletedEventArgs)
If CType(e.Result, Integer?) IsNot Nothing Then
If e.Result = 1 Then
HtmlPage.Window.Alert("Record Inserted Successfully")
End If
End If
End Sub
End Class
End Namespace
In the above code, btnCancel_click will clear all textboxes in the control.
Step 7: Open HomePage.Xaml.cs, and write the following code:
C#
private void btnLoadInsert_Click(object sender, RoutedEventArgs e)
{
canvMain.Children.Clear();
InsertPage ctrlInsert = new InsertPage();
canvMain.Children.Add(ctrlInsert);
}
VB.NET
private void btnLoadInsert_Click(object sender, RoutedEventArgs e)
{
canvMain.Children.Clear();
InsertPage ctrlInsert = new InsertPage();
canvMain.Children.Add(ctrlInsert);
}
The code creates object of ‘InsertPage’ user control and adds it as a children of the canvas.
Step 8: Run the project and click on ‘Get Insert’ button, you will get the following output:
Step 9: Insert values in textboxes and click on the ‘Save’ button. You will get the following output:
Close the browser.
Step 10: In the Silverlight project add a new user control, name it as ‘GetAllPage.xaml’. Add the following Xaml code to it:
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="SILV3_DMLClientApplication.GetAllPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid x:Name="dgEmp"
AutoGenerateColumns="False" >
<data:DataGrid.Columns>
<data:DataGridTextColumn Binding="{Binding EmpNo}" Header="EmpNo" Width="80"></data:DataGridTextColumn>
<data:DataGridTextColumn Binding="{Binding EmpName}" Header="EmpName" Width="150"></data:DataGridTextColumn>
<data:DataGridTextColumn Binding="{Binding Salary}" Header="Salary" Width="80"></data:DataGridTextColumn>
<data:DataGridTextColumn Binding="{Binding DeptNo}" Header="DeptNo" Width="80"></data:DataGridTextColumn>
</data:DataGrid.Columns>
</data:DataGrid>
<data:DataPager x:Name="dtPager" DisplayMode="FirstLastPreviousNextNumeric"
AutoEllipsis="True" PageSize="3"
Source="{Binding ItemsSource,ElementName=dgEmp}" IsEnabled="True">
</data:DataPager>
</Grid>
</UserControl>
The ‘DataPager’ element is used to specify the number of rows displayed in the datagrid.
Step 11: In the ‘GetAllPage.Xaml.cs’ or .vb add the following code:
C#
namespace SILV3_DMLClientApplication
{
public partial class GetAllPage : UserControl
{
MyRef.DMLServiceClient Proxy;
ObservableCollection<MyRef.clsEmployee> _colEmp;
public GetAllPage()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Proxy = new SILV3_DMLClientApplication.MyRef.DMLServiceClient();
Proxy.GetAllEmployeeCompleted += new EventHandler<SILV3_DMLClientApplication.MyRef.GetAllEmployeeCompletedEventArgs>(Proxy_GetAllEmployeeCompleted);
Proxy.GetAllEmployeeAsync();
}
void Proxy_GetAllEmployeeCompleted(object sender, SILV3_DMLClientApplication.MyRef.GetAllEmployeeCompletedEventArgs e)
{
if (e.Result != null)
{
_colEmp = e.Result;
dgEmp.ItemsSource = new PagedCollectionView(e.Result);
//dgEmp.ItemsSource = _colEmp;
}
}
}
}
VB.NET
Namespace SILV3_DMLClientApplication
Partial Public Class GetAllPage
Inherits UserControl
Private Proxy As MyRef.DMLServiceClient
Private _colEmp As ObservableCollection(Of MyRef.clsEmployee)
Public Sub New()
InitializeComponent()
End Sub
Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
Proxy = New SILV3_DMLClientApplication.MyRef.DMLServiceClient()
AddHandler Proxy.GetAllEmployeeCompleted, AddressOf Proxy_GetAllEmployeeCompleted
Proxy.GetAllEmployeeAsync()
End Sub
Private Sub Proxy_GetAllEmployeeCompleted(ByVal sender As Object, ByVal e As SILV3_DMLClientApplication.MyRef.GetAllEmployeeCompletedEventArgs)
If e.Result IsNot Nothing Then
_colEmp = e.Result
dgEmp.ItemsSource = New PagedCollectionView(e.Result)
'dgEmp.ItemsSource = _colEmp;
End If
End Sub
End Class
End Namespace
The ‘PagedCollectionView’ class is used for pagination.
Step 12: Open ‘HomePage.Xaml.cs’ and write the following code ‘btnLoadGetAll_Click’:
C#
private void btnLoadGetAll_Click(object sender, RoutedEventArgs e)
{
canvMain.Children.Clear();
GetAllPage ctrlgetAllPage = new GetAllPage();
canvMain.Children.Add(ctrlgetAllPage);
}
VB.NET
Private Sub btnLoadGetAll_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
canvMain.Children.Clear()
Dim ctrlgetAllPage As New GetAllPage()
canvMain.Children.Add(ctrlgetAllPage)
End Sub
Step 13: Run the Silverlight application and click on the ‘Get All’ button. You will get the following output:
Stop the application.
Step 14: To the Silverlight project, add a new Silverlight user control and name it as ‘UpdatePage.xaml’. Write the following xaml code:
<UserControl xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" x:Class="SILV3_DMLClientApplication.UpdatePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="590" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="LightCyan" Width="598" Height="590">
<dataFormToolkit:DataForm x:Name="dfUpdateEmp"
Margin="1,1,10,100" AutoGenerateFields="True"
Height="450" Width="580" AutoEdit="False"
CommandButtonsVisibility="Navigation,Edit,Commit" >
</dataFormToolkit:DataForm>
</Grid>
</UserControl>
One of the most important things in the above xaml code is the ‘CommandButtonVisibility’ property of the DataForm. This property will define only the ‘Navigation, Edit, Commit’ button.
Step 15: Add the following code in ‘UpdatePage.xaml.cs’:
C#
namespace SILV3_DMLClientApplication
{
public partial class UpdatePage : UserControl
{
MyRef.DMLServiceClient Proxy;
ObservableCollection<MyRef.clsEmployee> _colEmp;
public UpdatePage()
{
InitializeComponent();
dfUpdateEmp.EditEnded += new EventHandler<DataFormEditEndedEventArgs>(dfUpdateEmp_EditEnded);
}
void dfUpdateEmp_EditEnded(object sender, DataFormEditEndedEventArgs e)
{
Proxy.UpdateEmployeeCompleted += new EventHandler<SILV3_DMLClientApplication.MyRef.UpdateEmployeeCompletedEventArgs>(Proxy_UpdateEmployeeCompleted);
Proxy.UpdateEmployeeAsync((MyRef.clsEmployee)dfUpdateEmp.CurrentItem);
}
void Proxy_UpdateEmployeeCompleted(object sender, SILV3_DMLClientApplication.MyRef.UpdateEmployeeCompletedEventArgs e)
{
if ((int?)e.Result != null)
{
if (e.Result == 1)
{
HtmlPage.Window.Alert("Record Updated Successfully");
}
}
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Proxy = new SILV3_DMLClientApplication.MyRef.DMLServiceClient();
Proxy.GetAllEmployeeCompleted += new EventHandler<SILV3_DMLClientApplication.MyRef.GetAllEmployeeCompletedEventArgs>(Proxy_GetAllEmployeeCompleted);
Proxy.GetAllEmployeeAsync();
// dfUpdateEmp.CommandButtonsVisibility = DataFormCommandButtonsVisibility.All;
}
void Proxy_GetAllEmployeeCompleted(object sender, SILV3_DMLClientApplication.MyRef.GetAllEmployeeCompletedEventArgs e)
{
if (e.Result != null)
{
_colEmp = e.Result;
dfUpdateEmp.ItemsSource = e.Result;
}
}
}
}
VB.NET
Namespace SILV3_DMLClientApplication
Partial Public Class UpdatePage
Inherits UserControl
Private Proxy As MyRef.DMLServiceClient
Private _colEmp As ObservableCollection(Of MyRef.clsEmployee)
Public Sub New()
InitializeComponent()
AddHandler dfUpdateEmp.EditEnded, AddressOf dfUpdateEmp_EditEnded
End Sub
Private Sub dfUpdateEmp_EditEnded(ByVal sender As Object, ByVal e As DataFormEditEndedEventArgs)
AddHandler Proxy.UpdateEmployeeCompleted, AddressOf Proxy_UpdateEmployeeCompleted
Proxy.UpdateEmployeeAsync(CType(dfUpdateEmp.CurrentItem, MyRef.clsEmployee))
End Sub
Private Sub Proxy_UpdateEmployeeCompleted(ByVal sender As Object, ByVal e As SILV3_DMLClientApplication.MyRef.UpdateEmployeeCompletedEventArgs)
If CType(e.Result, Integer?) IsNot Nothing Then
If e.Result = 1 Then
HtmlPage.Window.Alert("Record Updated Successfully")
End If
End If
End Sub
Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
Proxy = New SILV3_DMLClientApplication.MyRef.DMLServiceClient()
AddHandler Proxy.GetAllEmployeeCompleted, AddressOf Proxy_GetAllEmployeeCompleted
Proxy.GetAllEmployeeAsync()
' dfUpdateEmp.CommandButtonsVisibility = DataFormCommandButtonsVisibility.All;
End Sub
Private Sub Proxy_GetAllEmployeeCompleted(ByVal sender As Object, ByVal e As SILV3_DMLClientApplication.MyRef.GetAllEmployeeCompletedEventArgs)
If e.Result IsNot Nothing Then
_colEmp = e.Result
dfUpdateEmp.ItemsSource = e.Result
End If
End Sub
End Class
End Namespace
When this control is loaded, it will call the ‘GetAllAsync’ method which will load all the records. The ‘EditEnded’ is implemented to give call to the ‘UpdateEmployee’ method asynchronously.
Step 16: Open HomePage.xaml.cs and write the following code ‘btnLoadUpdate_Click’ method:
C#
private void btnLoadUpdate_Click(object sender, RoutedEventArgs e)
{
canvMain.Children.Clear();
UpdatePage ctrlUpdPage = new UpdatePage();
canvMain.Children.Add(ctrlUpdPage);
}
VB.NET
Private Sub btnLoadUpdate_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
canvMain.Children.Clear()
Dim ctrlUpdPage As New UpdatePage()
canvMain.Children.Add(ctrlUpdPage)
End Sub
The above code will create an object of ‘UpdatePage’ and add it in the canvas ‘canvMain’.
Step 17: Run the application and click on ‘Get Update’ button which will load the ‘UpdatePage’ user control as shown below:
User can use the pager control and click on the edit button. When the textboxes are updated and the ‘OK’ button is clicked, the following output will be displayed:
One of the nice things here is that DataForm control provides facility for insert, update, delete and pagination. But most of the time, the user wants to design his own window for performing operation like insert, so the DataForm control can be more suitable for performing operations like update and delete.
Note: These User Controls can also be used by the navigation application template provided by Silverlight and also in RIA services.
Conclusion: Silverlight user control is one of the flexible mechanisms provided for developing isolated visuals and these can be loaded as and when required. The entire source code of this article can be downloaded over here
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @
maheshdotnet or connect with him on
LinkedIn