Silverlight 4.0 Data Manipulation and Navigation using CollectionViewSource with WCF RIA Services

This article explains the navigation features available in “CollectionViewSource.” We will also cover CRUD (Create, Read, Update and Delete) operations using “CollectionViewSource.”

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
July 26, 2010
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

My previous article introduced “CollectionViewSource” in Silverlight 4.0. You can check it out here.

To make this article simple, I managed to create a simple Silverlight 4.0 application which consumes a WCF RIA Service created using the WCF RIA Service Library. If you are not familiar with developing applications using the WCF RIA Service Library and Silverlight 4.0, check out a beginner’s article.

The solution was developed using Microsoft Visual Studio 2010 Ultimate Edition with Microsoft Silverlight 4.0 on Windows 7 Ultimate edition. I didn’t really test it in any other environment. I request that you post in the discussion area if you have any problems with execution.

Navigating through data using CollectionViewSource in Silverlight: screen design

Way back in Visual Basic 6.0, we used to have RecordSet. It used to have the following methods: MoveNext, MovePrevious, MoveLast and MoveFirst. Those methods are mainly used to maintain the “current” object in memory so that it could be bound to controls on the form. We can use “CollectionViewSource” to make use of such functionality.

Let us consider the following:

<UserControl x:Class="SLBusinessAppWithRiaLib.CvsNavigation"

 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:DesignHeight="300" d:DesignWidth="400"

 xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Width="500" Height="500">

 <UserControl.Resources>

 <CollectionViewSource x:Key="cvsEmp"/>

 </UserControl.Resources>

 

 <Grid x:Name="LayoutRoot" Background="White">

 <Grid.RowDefinitions>

 <RowDefinition Height="Auto" />

 <RowDefinition Height="Auto" />

 <RowDefinition Height="*" />

 </Grid.RowDefinitions>

 <Grid x:Name="lytEmpForm" Margin="8" DataContext="{Binding Source={StaticResource cvsEmp}}">

 <Grid.RowDefinitions>

 <RowDefinition Height="Auto"/>

 <RowDefinition Height="Auto"/>

 <RowDefinition Height="Auto"/>

 <RowDefinition Height="Auto"/>

 </Grid.RowDefinitions>

 <Grid.ColumnDefinitions>

 <ColumnDefinition Width="0.20*"/>

 <ColumnDefinition Width="0.50*"/>

 <ColumnDefinition Width="0.30*"/>

 </Grid.ColumnDefinitions>

 <sdk:Label x:Name="lblEmpno" Margin="8" Content="Empno:"/>

 <sdk:Label x:Name="lblEname" Margin="8" Content="Ename:" Grid.Row="1"/>

 <sdk:Label x:Name="lblSal" Margin="8" Content="Salary:" Grid.Row="2"/>

 <sdk:Label x:Name="lblDeptno" Margin="8" Content="Deptno:" Grid.Row="3"/>

 <TextBox x:Name="txtEmpno" Grid.Column="1" Margin="8" Height="24" Text="{Binding Path=empno, Mode=TwoWay}"/>

 <TextBox x:Name="txtEname" Grid.Column="1" Margin="8" Grid.Row="1" Height="24" Text="{Binding Path=ename, Mode=TwoWay}"/>

 <TextBox x:Name="txtSal" Grid.Column="1" Margin="8" Grid.Row="2" Height="24" Text="{Binding Path=sal, Mode=TwoWay}"/>

 <TextBox x:Name="txtDeptno" Grid.Column="1" Margin="8" Grid.Row="3" Height="24" Text="{Binding Path=deptno, Mode=TwoWay}"/>

 </Grid>

 <StackPanel x:Name="lytBtns" Margin="8" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Left">

 <Button x:Name="btnFirst" Content="First" Margin="0,0,8,0" Width="35" Height="25"/>

 <Button x:Name="btnPrevious" Content="Previous" Margin="0,0,8,0" Width="60" Height="25"/>

 <Button x:Name="btnNext" Content="Next" Margin="0,0,8,0" Width="45" Height="25"/>

 <Button x:Name="btnLast" Content="Last" Margin="0,0,8,0" Width="45" Height="25"/>

 </StackPanel>

 <sdk:DataGrid 

 x:Name="dgEmp"

 Margin="8" Grid.Row="2" MinHeight="200" IsReadOnly="True"

 ItemsSource="{Binding Source={StaticResource cvsEmp}}"/>

 

 </Grid>

</UserControl>

The screen design would look similar to the following:

I will explain the above code in upcoming sections.

Explanation of screen design

This section explains the code in the previous section. The following is the code which declares “CollectionViewSource”:

 <UserControl.Resources>

 <CollectionViewSource x:Key="cvsEmp"/>

 </UserControl.Resources>

All of the textboxes are declared with “Two-Way” binding (with the respective fields) so that they will pull and push data into the “CollectionViewSource.” You can observe the declarations below:

 <TextBox x:Name="txtEmpno" Grid.Column="1" Margin="8" Height="24" Text="{Binding Path=empno, Mode=TwoWay}"/>

 <TextBox x:Name="txtEname" Grid.Column="1" Margin="8" Grid.Row="1" Height="24" Text="{Binding Path=ename, Mode=TwoWay}"/>

 <TextBox x:Name="txtSal" Grid.Column="1" Margin="8" Grid.Row="2" Height="24" Text="{Binding Path=sal, Mode=TwoWay}"/>

 <TextBox x:Name="txtDeptno" Grid.Column="1" Margin="8" Grid.Row="3" Height="24" Text="{Binding Path=deptno, Mode=TwoWay}"/>

All of the above textboxes are contained in a Grid layout. The Grid layout acts as a data context for the above list of textboxes. You can observe the definition of the Grid layout as follows:

 <Grid x:Name="lytEmpForm" Margin="8" DataContext="{Binding Source={StaticResource cvsEmp}}">

To list all objects in “CollectionViewSource,” I used a DataGrid. The DataGrid is made to bind to “CollectionViewSource” directly, as shown below:

 <sdk:DataGrid 

 x:Name="dgEmp"

 Margin="8" Grid.Row="2" MinHeight="200" IsReadOnly="True"

 ItemsSource="{Binding Source={StaticResource cvsEmp}}"/>

To display buttons (navigation buttons) adjacent to each other, I used a StackPanel with a horizontal orientation. You can understand the same from the code below:

 <StackPanel x:Name="lytBtns" Margin="8" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Left">

Code

The following is code-behind for the screen provided in the previous section:

Private oCtxt As New BusinessLib.Web.EmpMgrDomainSvc

Private oCvsEmp As CollectionViewSource

 

Public Sub New()

InitializeComponent()

 

oCvsEmp = CType(Me.Resources("cvsEmp"), CollectionViewSource)

oCvsEmp.Source = oCtxt.emps

oCtxt.Load(oCtxt.GetEmpsQuery())

 'Me.dgEmp.ItemsSource = oCvsEmp.View 'if not using declarative syntax

 

End Sub

 

Private Sub btnFirst_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnFirst.Click

oCvsEmp.View.MoveCurrentToFirst()

 'Me.lytEmpForm.DataContext = oCvsEmp.View.CurrentItem 'if not using declarative syntax

End Sub

 

Private Sub btnLast_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnLast.Click

oCvsEmp.View.MoveCurrentToLast()

End Sub

 

Private Sub btnPrevious_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnPrevious.Click

oCvsEmp.View.MoveCurrentToPrevious()

If oCvsEmp.View.IsCurrentBeforeFirst Then

oCvsEmp.View.MoveCurrentToFirst()

End If

End Sub

 

Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnNext.Click

oCvsEmp.View.MoveCurrentToNext()

If oCvsEmp.View.IsCurrentAfterLast Then

oCvsEmp.View.MoveCurrentToLast()

End If

End Sub

“CollectionViewSource” is loaded using the following code:

oCvsEmp = CType(Me.Resources("cvsEmp"), CollectionViewSource)

oCvsEmp.Source = oCtxt.emps

oCtxt.Load(oCtxt.GetEmpsQuery())

The current context of “CollectionViewSource” is assigned to controls using the following:

 <Grid x:Name="lytEmpForm" Margin="8" DataContext="{Binding Source={StaticResource cvsEmp}}">

To change the current context (object being bound to controls) we can use MoveCurrentToNext, MoveCurrentToPrevious, MoveCurrentToFirst or MoveCurrentToLast. All of these methods belong to the “View” object of “CollectionViewSource.”

Once we click on the “First” button, it should show the following result:

Manipulating data using CollectionViewSource in Silverlight

In the previous section, we saw how to navigate using “CollectionViewSource.” In this section, we will concentrate on manipulating data using “CollectionViewSource.” I made a couple of modifications to the previous screen design, so that it would look something like the following:

We can search for an object in a “CollectionViewSource” using the following code:

Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSearch.Click

Dim oEmp = CType(oCvsEmp.View.SourceCollection,

System.ServiceModel.DomainServices.Client.EntitySet(Of BusinessLib.Web.emp)).SingleOrDefault(Function(p) p.empno = Me.txtSearchEmpno.Text)

 

If oEmp Is Nothing Then

 MessageBox.Show("Employee not found")

Else

oCvsEmp.View.MoveCurrentTo(oEmp)

End If

End Sub

Adding a new object to “CollectionViewSource” is a simple, indirect process. All you have to do is add a new object to the context, which would automatically appear in “CollectionViewSource.” To reflect the same in the controls, we need to move the “current” of “CollectionViewSource” to the newly added object as follows:

Private Sub btnAddNew_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnAddNew.Click

Dim oEmp As New BusinessLib.Web.emp

oCtxt.emps.Add(oEmp)

oCvsEmp.View.MoveCurrentTo(oEmp)

End Sub

We can use the same technique to delete an object in “CollectionViewSource” as follows:

Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnDelete.Click

If Me.oCvsEmp.View.CurrentItem Is Nothing Then

 MessageBox.Show("Employee not selected to delete")

Exit Sub

End If

oCtxt.emps.Remove(Me.oCvsEmp.View.CurrentItem)

End Sub

All of the modifications made to the main context (indirectly done using “CollectionViewSource”) can be saved using the following:

Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSave.Click

Try

oCtxt.SubmitChanges(AddressOf OnSubmitCompleted, Nothing)

Catch ex As Exception

 MessageBox.Show(ex.Message)

End Try

End Sub

Error handling while saving can be done using the following:

Private Sub OnSubmitCompleted(ByVal so As SubmitOperation)

If (so.HasError) Then

 MessageBox.Show(String.Format("Save Failed: {0}", so.Error.Message))

so.MarkErrorAsHandled()

Else

 MessageBox.Show("Saved Successfully!")

End If

End Sub

Once you save, the output will look similar to the following:

My next article focuses on more features of the “CollectionViewSource” element. I hope you enjoyed the article; any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com

blog comments powered by Disqus
SILVERLIGHT ARTICLES

- With Silverlight Gone, Whither SharePoint?
- Silverlight in the News
- Silverlight Has a Bright Future
- Windows 8 Effects on .Net and Silverlight De...
- Microsoft`s SkyDrive Abandons Silverlight
- Silverlight Developers Unhappy with Windows ...
- Best Silverlight Examples
- How to install Silverlight for Windows Phone
- Microsoft Reveals Silverlight 5 Features
- Silverlight News: SRS and Microsoft to Bring...
- Silverlight 4.0: Paging Through Data using D...
- Silverlight 4.0: Navigating Data Using Domai...
- Silverlight 4.0: Filtering Data Using Domain...
- Silverlight 4.0: Sorting and Grouping Data w...
- Silverlight 4.0: Query Parameters of DomainD...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 3 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials