Introduction to Binding ComboBox and DataGrid Controls in Silverlight 2.0

This is my seventh article in a series focusing on Silverlight 2.0 development using Visual Studio 2008. In this article, I will introduce you to binding WCF object collections to ComboBox. We will also explore cascading ComboBoxes and the DataGrid relative to ComboBox.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 10
February 04, 2009
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

This article assumes that you have minimum knowledge of technologies like “LINQ to SQL,” “WCF,” “Silverlight” and so forth. If you don’t, and if you need step-by-step information about the above technologies, please go through the following links.

If you are new to Silverlight 2.0 development, please refer to the following articles before going ahead (all available at http://www.aspfree.com/cp/bio/Jagadish-Chatarji/):

  • Beginning Silverlight 2.0 Development using Visual Studio 2008

  • Developing a Silverlight 2.0 Application Consuming a WCF Service using Visual Studio 2008

  • Silverlight 2.0 Application Development with LINQ to SQL and WCF Service (HIGHLY RECOMMENDED)


This article is based on the following configuration:



To make this article simple, I created a table structure as seen at http://cid-41050f68f010a662.skydrive.live.com/self.aspx/Public/images/DeptEmp.gif

The entire source code for this article is available in the form of a free downloadable zip file. The solution was developed using Microsoft Visual Studio 2008 Team Edition (with SP1) with Microsoft SQL Server 2008 Developer Edition on Microsoft Windows Server 2003 Standard Edition (with SP2) with Silverlight 2.0 (RTM). I didn’t really test it in any other environment. I request that you post in the discussion area if you have any problems in execution.

Developing WCF Service to serve Business (Entity) Objects collection using LINQ to SQL

Let us start with a new solution:

  • Create a new Visual Studio 2008 solution.

  • Add a new WCF Service project named “DemoEmpService.”

  • Change “Service1” to “EmpService” throughout the project (steps are shown in my previous articles).

  • Add a “LINQ to SQL Classes” item to the project (“DemoEmp.dbml”).

  • Using “Server Explorer,” drag and drop “Emp” and “Dept” tables as shown in the following image.

  • Modify “IEmpService.vb” as shown below:


<ServiceContract()> _

Public Interface IEmpService


<OperationContract()> _

Function GetEmployee(ByVal empno As Integer) As Emp


<OperationContract()> _

Function GetEmployeeList() As List(Of Emp)


<OperationContract()> _

Function GetDepartmentList() As List(Of Dept)


<OperationContract()> _

Function GetEmployeeListByDept(ByVal deptno As Integer) As List(Of Emp)


End Interface



  • Implement the same in the “EmpService” (service) class as follows:


Imports System.Data.Linq


' NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.

Public Class EmpService

Implements IEmpService


Public Sub New()

End Sub


Public Function GetEmployeeList() As System.Collections.Generic.List(Of Emp) Implements IEmpService.GetEmployeeList

Using ctxt As New DemoEmpDataContext

ctxt.ObjectTrackingEnabled = False

Return ctxt.Emps.ToList

End Using

End Function


Public Function GetEmployee(ByVal empno As Integer) As Emp Implements IEmpService.GetEmployee

Dim objEmp As Emp = Nothing


Using ctxt As New DemoEmpDataContext

'retrieve emp row

objEmp = ctxt.GetTable(Of Emp).SingleOrDefault(Function(p) p.Empno = empno)

End Using


Return objEmp

End Function


Public Function GetDepartmentList() As System.Collections.Generic.List(Of Dept) Implements IEmpService.GetDepartmentList

Using ctxt As New DemoEmpDataContext

ctxt.ObjectTrackingEnabled = False

Return ctxt.Depts.ToList

End Using

End Function


Public Function GetEmployeeListByDept(ByVal deptno As Integer) As System.Collections.Generic.List(Of Emp) Implements IEmpService.GetEmployeeListByDept

Using ctxt As New DemoEmpDataContext

Dim opt As New DataLoadOptions

opt.LoadWith(Of Dept)(Function(d) d.Emps)

ctxt.LoadOptions = opt

ctxt.ObjectTrackingEnabled = False

 

Dim oDept As Dept = ctxt.Depts.Where(Function(d) d.Deptno = deptno).FirstOrDefault

Return If(oDept Is Nothing, Nothing, oDept.Emps.ToList)

End Using

End Function


End Class



Binding Object Collections Silverlight 2.0 ComboBox control dynamically

Now we have to develop a Silverlight 2.0 page which can consume our previously developed WCF Service. In this section, I will simply develop a Silverlight 2.0 page which has only a ComboBox control on it, and finally bind it to WCF object collection dynamically.

The following are the steps necessary to develop the above Silverlight 2.0 page:


  • Add a new “Silverlight” project (“DemoSL”) to the solution. This in turn will add a “DemoSL.Web” project (Silverlight hoster application) to the solution. Detailed steps are provided in previous articles.

  • Add a new “Silverlight user control” (“Page6.xaml”) to the “DemoSL” project and modify “Application_Startup” in “App.xaml” as follows:


Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup

Me.RootVisual = New Page6()


End Sub

  • Modify “Page6.xaml” as follows:


<UserControl x:Class="DemoSL.Page6"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="400" Height="300">

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

 <StackPanel Height="36" Width="301" Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0">

 <TextBlock Height="16" x:Name="lblDept" Width="100" Text="Select Dept:" TextWrapping="Wrap"/>

 <ComboBox Height="20" x:Name="cboDept" Width="184"/>

 </StackPanel>

 <TextBlock Height="26" HorizontalAlignment="Left" x:Name="lblMsg" Width="350" Text="" TextWrapping="Wrap" Margin="10,0,0,0"/>

 </StackPanel>

</UserControl>


The code behind the above markup is as follows:


Partial Public Class Page6

Inherits UserControl


Dim objService As New EmpService.EmpServiceClient


Public Sub New

InitializeComponent()

InitiateHandlers()

End Sub


Private Sub InitiateHandlers()

AddHandler objService.GetDepartmentListCompleted, AddressOf DeptListFetched

End Sub



Private Sub Page6_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

objService.GetDepartmentListAsync()

End Sub


Private Sub DeptListFetched(ByVal sender As Object, ByVal e As EmpService.GetDepartmentListCompletedEventArgs)

Me.cboDept.DisplayMemberPath = "Dname"

Me.cboDept.ItemsSource = e.Result

End Sub



Private Sub cboDept_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboDept.SelectionChanged

Me.lblMsg.Text = "You selected: " & CType(Me.cboDept.SelectedItem, EmpService.Dept).Deptno

End Sub


End Class


Explanation for the code is available in the last section.

It should give the output as follows:


If you could not execute your application (or if it is throwing any errors), please follow my previous articles, which discuss troubleshooting.

Binding Object Collections to cascading Silverlight 2.0 ComboBoxes

In the previous section, we make object collection bind to a single ComboBox. However, there will be times where cascade-type binding for ComboBoxes is necessary. In simple words, we will bind the first ComboBox (say Dept ComboBox) to one collection. Once the user selects an item in the first ComboBox, the second ComboBox (say Emp ComboBox) must be bound to related items.

The following is the markup for designing Silverlight UI with two ComboBoxes:


<UserControl x:Class="DemoSL.Page7"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="400" Height="300" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">

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

 <StackPanel Height="36" Width="301" Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0">

 <TextBlock Height="16" x:Name="lblDept" Width="100" Text="Select Dept:" TextWrapping="Wrap"/>

 <ComboBox Height="20" x:Name="cboDept" Width="184" Canvas.ZIndex="100"/>

 </StackPanel>

 <StackPanel Height="36" Width="301" Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0">

 <TextBlock Height="16" x:Name="lblEmp" Width="100" Text="Select Employee:" TextWrapping="Wrap"/>

 <ComboBox Height="20" x:Name="cboEmp" Width="184" Canvas.ZIndex="100"/>

 </StackPanel>

 <TextBlock Height="26" HorizontalAlignment="Left" x:Name="lblMsg" Width="350" Text="" TextWrapping="Wrap" Margin="10,0,0,0"/>

 </StackPanel>


</UserControl>


The following is the code behind the above markup:


Partial Public Class Page7

Inherits UserControl


Dim objService As New EmpService.EmpServiceClient


Public Sub New()

InitializeComponent()

InitiateHandlers()

End Sub


Private Sub InitiateHandlers()

AddHandler objService.GetDepartmentListCompleted, AddressOf DeptListFetched

AddHandler objService.GetEmployeeListByDeptCompleted, AddressOf EmpListFetched

End Sub


Private Sub Page7_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

objService.GetDepartmentListAsync()

End Sub


Private Sub DeptListFetched(ByVal sender As Object, ByVal e As EmpService.GetDepartmentListCompletedEventArgs)

Me.cboDept.DisplayMemberPath = "Dname"

Me.cboDept.ItemsSource = e.Result

End Sub


Private Sub cboDept_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboDept.SelectionChanged

Me.lblMsg.Text = "Fetching Employees.."

Dim oDept As EmpService.Dept = Me.cboDept.SelectedItem

objService.GetEmployeeListByDeptAsync(oDept.Deptno)

End Sub


Private Sub EmpListFetched(ByVal sender As Object, ByVal e As EmpService.GetEmployeeListByDeptCompletedEventArgs)

Me.cboEmp.DisplayMemberPath = "Ename"

Me.cboEmp.ItemsSource = e.Result

Me.lblMsg.Text = "Fetched!"

End Sub



End Class


The explanation for the code is available in the last section.

It should give the output as follows:


Binding Object Collections to Silverlight 2.0 ComboBox cascading with DataGrid

In the previous example, we saw the collection being bound to the ComboBox dynamically. In this section, we will have related binding between a ComboBox and DataGrid.

The following is the Silverlight 2.0 markup which displays both ComboBox and DataGrid in a detailed fashion:


<UserControl x:Class="DemoSL.Page8"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="400" Height="300" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">

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

 <StackPanel Height="36" Width="301" Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0">

 <TextBlock Height="16" x:Name="lblDept" Width="100" Text="Select Dept:" TextWrapping="Wrap"/>

 <ComboBox Height="20" x:Name="cboDept" Width="184" Canvas.ZIndex="100" DisplayMemberPath="Dname" />

 </StackPanel>

 <TextBlock Height="26" HorizontalAlignment="Left" x:Name="lblMsg" Width="350" Text="" TextWrapping="Wrap" Margin="10,0,0,0"/>

 <ScrollViewer Height="243" HorizontalAlignment="Stretch" Width="Auto" Margin="10,0,0,0">

 <data:DataGrid x:Name="dgEmployees"/>

 </ScrollViewer>

 </StackPanel>


</UserControl>


You can copy the entire code from the previous section and modify as follows:


Partial Public Class Page8

Inherits UserControl


.

.


Private Sub EmpListFetched(ByVal sender As Object, ByVal e As EmpService.GetEmployeeListByDeptCompletedEventArgs)

Me.dgEmployees.ItemsSource = e.Result

Me.lblMsg.Text = "Fetched!"

End Sub


End Class


It should give the output as follows:


Detailed Explanation

Let us try to understand the code in the previous sections:

Binding Dropdown to Object Collection:

We are consuming the WCF service with the following statements:


Dim objService As New EmpService.EmpServiceClient

objService.GetDepartmentListAsync()


As the communication takes place in an asynchronous manner, the "DeptListFetched” method gets executed when the fetching is completed. This callback mechanism is managed by using delegation as follows:


AddHandler objService.GetDepartmentListCompleted, AddressOf DeptListFetched


The “DeptListFetched” method gets executed by the Silverlight framework once the WCF service responds. The “GetDepartmentList” method sends back a collection of objects and gets directly filled into “GetDepartmentListCompletedEventArgs” (in this case, it is the “e” parameter in “DeptListFetched” method). Finally, we assign the same to the ComboBox as follows:


Private Sub DeptListFetched(ByVal sender As Object, ByVal e As EmpService.GetDepartmentListCompletedEventArgs)

Me.cboDept.DisplayMemberPath = "Dname"

Me.cboDept.ItemsSource = e.Result

End Sub


Cascading Dropdowns with Object Collection binding:

This works very similar to the binding dropdown, except that the second dropdown gets bound every time when the user selects an item in the first drop down.

You can observe the following event, which fetches employee information from the WCF service based on the user-selected department (in the first ComboBox):

Private Sub cboDept_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboDept.SelectionChanged

Me.lblMsg.Text = "Fetching Employees.."

Dim oDept As EmpService.Dept = Me.cboDept.SelectedItem

objService.GetEmployeeListByDeptAsync(oDept.Deptno)

End Sub


The second dropdown gets bound to the list of employees during callback, as shown in the following code:


Private Sub EmpListFetched(ByVal sender As Object, ByVal e As EmpService.GetEmployeeListByDeptCompletedEventArgs)

Me.cboEmp.DisplayMemberPath = "Ename"

Me.cboEmp.ItemsSource = e.Result

Me.lblMsg.Text = "Fetched!"

End Sub



In my upcoming articles, we will see more and more examples of Silverlight 2.0 development together with LINQ to SQL and WCF. I hope you enjoyed the article and any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com

blog comments powered by Disqus
BRAINDUMP ARTICLES

- Microsoft Windows 8 Committed to Cloud Compu...
- Independent Developers Favor Windows Phone 7
- Dell Introduces VMware-based Cloud
- Microsoft and Skype Agree to Acquisition Deal
- Transfer Contacts in Microsoft Outlook
- Zune`s Next Steps
- Safari Books Online Review
- Does Microsoft Get Touch Screens Now?
- Microsoft`s Record Quarterly Earnings Not En...
- Basic Operations and Registers in Assembly
- Assembly Coding within Visual C/C++ IDE
- New Microsoft Office Coming with a Twist
- Microsoft`s FUSE Labs Unveils Spindex Social...
- HP Slate with Windows 7: Dead or Alive?
- Windows Phone 7 Mobile OS to Rival Android a...

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 8 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials