Exchanging Data between XAP files using Local Collection API in Silverlight 3

Posted by: Mahesh Sabnis , on 2/20/2010, in Category Silverlight 2, 3, 4 and 5
Views: 34973
Abstract: With the LocalConnection API, Silverlight 3 has provided a cool feature for sharing data across XAPs hosted on the same .aspx page. In this article, we will explore how to use this feature.
Exchanging Data between XAP files using Local Collection API in Silverlight 3
         
I recently came across a requirement on exchanging data between two XAPs hosted in single .NET page. In this article we will discuss one of the most important features of Silverlight 3.0 that is ‘LocalConnectionAPI’. In Silverlight 3.0, the following new classes were introduced:
·         LocalMessageSender : This is the sending end of the message channel.
·         LocalMessageReceiver: This is the receiving end of the messaging channel.
Using the following steps we can implement LocalConnection with Silverlight.
Step 1: Open VS2008 and create a blank solution, name it as ‘SILV3_SharingDataAcross_2_XAPS’.
Step 2: To this solution add a new Silverlight Application, name it as ‘SILV3_DataPresenter’. This action will create web host application.
Step 3: To the same solution, add a new Silverlight project, name it as ‘SILV3_DataFilter’.
Step 4: Open the MainPage.Xaml of the ’SILV3_DataFilter’ and add following XAML Code:
<Grid x:Name="LayoutRoot" Width="170" Height="40">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="70"></ColumnDefinition>
        <ColumnDefinition Width="100"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Enter Value" Grid.Column="0"></TextBlock>
    <TextBox Grid.Column="1" Width="90" x:Name="txtData" TextChanged="txtData_TextChanged"></TextBox>
</Grid>
 
Step 5: In the MainPage.Xaml.cs add the following code. Add a reference to System.Windows.Messaging namespace:
C#
LocalMessageSender dataSender = new LocalMessageSender("DataToFilter");
 
    private void txtData_TextChanged(object sender, TextChangedEventArgs e)
    {
        //Provides the data for messaging
        EventHandler<SendCompletedEventArgs> senderHandler = null;
 
        senderHandler =
            (strData, evt) =>
            {
                Dispatcher.BeginInvoke(() =>
                {
                    dataSender.SendCompleted -= senderHandler;
                });
 
            };
 
        dataSender.SendCompleted += senderHandler;
 
        //Start Asynchronous Messag Sending
        dataSender.SendAsync(txtData.Text);
 
    }
VB.NET
Private dataSender As New LocalMessageSender("DataToFilter")
      Private Sub txtData_TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
            'Provides the data for messaging
            Dim senderHandler As EventHandler(Of SendCompletedEventArgs) = Nothing
            senderHandler = Function(strData, evt) AnonymousMethod1(strData, evt, senderHandler)
            AddHandler dataSender.SendCompleted, senderHandler
            'Start Asynchronous Messag Sending
            dataSender.SendAsync(txtData.Text)
 
End Sub
     
Private Function AnonymousMethod1(ByVal strData As Object, ByVal evt As Object, ByVal senderHandler As EventHandler(Of SendCompletedEventArgs)) As EventHandler
                  Dispatcher.BeginInvoke(Function() AnonymousMethod2(senderHandler))
End Function
     
Private Function AnonymousMethod2(ByVal senderHandler As EventHandler(Of SendCompletedEventArgs)) As Boolean
            RemoveHandler dataSender.SendCompleted, senderHandler
            Return True
End Function
The above code initiates sender channel of name ‘DataToFilter’. The TextChanged event sends data from the textbox asynchronously.
Step 6: In the ‘SILV3_DataPresenter’ project, open the MainPage.Xaml file and write the following XAML Code:
<Grid x:Name="LayoutRoot" Height="470">
    <Grid.RowDefinitions>
        <RowDefinition Height="30"></RowDefinition>
        <RowDefinition Height="200"></RowDefinition>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Text="The Filtered Data"></TextBlock>
    <data:DataGrid x:Name="dgData" Grid.Row="1"></data:DataGrid>
</Grid>
 
Step 7: In the ‘SILV3_DataPresenter’ project add a new class and name it as ‘clsPatient.cs’ and add following code in it:
C#
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
 
namespace SILV3_DataPresenter
{
    public class clsPatient
    {
        public int PatientId { get; set; }
        public string PatientName { get; set; }
        public int Age { get; set; }
        public string Dieses { get; set; }
    }
 
    public class PatientCollection : ObservableCollection<clsPatient>
    {
        public PatientCollection()
        {
            Add(new clsPatient() { PatientId = 101, PatientName = "Anand", Age = 56, Dieses = "Maleria" });
            Add(new clsPatient() { PatientId = 102, PatientName = "Makran", Age = 26, Dieses = "Toiphide" });
            Add(new clsPatient() { PatientId = 103, PatientName = "Sanjay", Age = 46, Dieses = "Flue" });
            Add(new clsPatient() { PatientId = 104, PatientName = "Rajan", Age = 66, Dieses = "Cynus" });
            Add(new clsPatient() { PatientId = 105, PatientName = "Amey", Age = 36, Dieses = "Cold" });
            Add(new clsPatient() { PatientId = 106, PatientName = "Sudhir", Age = 56, Dieses = "Feaver" });
            Add(new clsPatient() { PatientId = 107, PatientName = "Shailesh", Age = 36, Dieses = "Maleria" });
            Add(new clsPatient() { PatientId = 108, PatientName = "Ajay", Age = 23, Dieses = "Cold" });
            Add(new clsPatient() { PatientId = 109, PatientName = "Shrad", Age = 36, Dieses = "Flue" });
            Add(new clsPatient() { PatientId = 1010, PatientName = "Vinit", Age = 66, Dieses = "Maleria" });
        }
    }
}
 
VB.NET
Imports System
Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Ink
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports System.Collections.ObjectModel
 
Namespace SILV3_DataPresenter
      Public Class clsPatient
            Private privatePatientId As Integer
            Public Property PatientId() As Integer
                  Get
                        Return privatePatientId
                  End Get
                  Set(ByVal value As Integer)
                        privatePatientId = value
                  End Set
            End Property
            Private privatePatientName As String
            Public Property PatientName() As String
                  Get
                        Return privatePatientName
                  End Get
                  Set(ByVal value As String)
                        privatePatientName = value
                  End Set
            End Property
            Private privateAge As Integer
            Public Property Age() As Integer
                  Get
                        Return privateAge
                  End Get
                  Set(ByVal value As Integer)
                        privateAge = value
                  End Set
            End Property
            Private privateDieses As String
            Public Property Dieses() As String
                  Get
                        Return privateDieses
                  End Get
                  Set(ByVal value As String)
                        privateDieses = value
                  End Set
            End Property
      End Class
 
      Public Class PatientCollection
            Inherits ObservableCollection(Of clsPatient)
            Public Sub New()
                  Add(New clsPatient() With {.PatientId = 101, .PatientName = "Anand", .Age = 56, .Dieses = "Maleria"})
                  Add(New clsPatient() With {.PatientId = 102, .PatientName = "Makran", .Age = 26, .Dieses = "Toiphide"})
                  Add(New clsPatient() With {.PatientId = 103, .PatientName = "Sanjay", .Age = 46, .Dieses = "Flue"})
                  Add(New clsPatient() With {.PatientId = 104, .PatientName = "Rajan", .Age = 66, .Dieses = "Cynus"})
                  Add(New clsPatient() With {.PatientId = 105, .PatientName = "Amey", .Age = 36, .Dieses = "Cold"})
                  Add(New clsPatient() With {.PatientId = 106, .PatientName = "Sudhir", .Age = 56, .Dieses = "Feaver"})
                  Add(New clsPatient() With {.PatientId = 107, .PatientName = "Shailesh", .Age = 36, .Dieses = "Maleria"})
                  Add(New clsPatient() With {.PatientId = 108, .PatientName = "Ajay", .Age = 23, .Dieses = "Cold"})
                  Add(New clsPatient() With {.PatientId = 109, .PatientName = "Shrad", .Age = 36, .Dieses = "Flue"})
                  Add(New clsPatient() With {.PatientId = 1010, .PatientName = "Vinit", .Age = 66, .Dieses = "Maleria"})
            End Sub
      End Class
End Namespace
 
Step 7: In the MainPage.Xaml.cs write the following code:
C#
LocalMessageReceiver dataReceiver;
 
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    PatientCollection patientRecord = new PatientCollection ();
 dgData.ItemsSource = patientRecord;
 
    //Attach REceiver with Sender
    dataReceiver = new LocalMessageReceiver("DataToFilter");
 
    //Now receive the MEssage
    dataReceiver.MessageReceived += (strData, evt) =>
        {
            //Process the received data
            Dispatcher.BeginInvoke(() =>
                {
                    var filteredData = from patient in patientRecord
                                       where patient.PatientName.StartsWith(evt.Message)
                                       select patient;
 
                    dgData.ItemsSource = filteredData;
                });
        };
 
    //Listen the Message Received, this does not block the thread
    dataReceiver.Listen();
}
VB.NET
Private dataReceiver As LocalMessageReceiver
 
Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
      Dim patientRecord As New PatientCollection()
 dgData.ItemsSource = patientRecord
 
      'Attach REceiver with Sender
      dataReceiver = New LocalMessageReceiver("DataToFilter")
 
      'Now receive the MEssage
      AddHandler dataReceiver.MessageReceived, Function(strData, evt) AnonymousMethod1(strData, evt, patientRecord)
 
      'Listen the Message Received, this does not block the thread
      dataReceiver.Listen()
End Sub
 
Private Function AnonymousMethod1(ByVal strData As Object, ByVal evt As Object, ByVal patientRecord As PatientCollection) As Boolean
            Dispatcher.BeginInvoke(Function() AnonymousMethod2(evt, patientRecord))
      Return True
End Function
 
Private Function AnonymousMethod2(ByVal evt As Object, ByVal patientRecord As PatientCollection) As Boolean
      Dim filteredData = From patient In patientRecord _
                         Where patient.PatientName.StartsWith(evt.Message) _
                         Select patient
      dgData.ItemsSource = filteredData
      Return True
End Function
 
The above code subscribes to the channel created by sender Silverlight application and starts receiving and processing data.
Step 8: In the ASP.NET test page add both XAP files as shown below:
<object data="data:application/x-silverlight-2,"
            type="application/x-silverlight-2" width="100%" style="height: 92px">
    <param name="source" value="ClientBin/SILV3_DataFilter.xap"/>
    <param name="onError" value="onSilverlightError" />
    <param name="background" value="white" />
    <param name="minRuntimeVersion" value="3.0.40624.0" />
    <param name="autoUpgrade" value="true" />
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
        <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
    </a>
</object>
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
    <param name="source" value="ClientBin/SILV3_DataPresenter.xap"/>
    <param name="onError" value="onSilverlightError" />
    <param name="background" value="white" />
    <param name="minRuntimeVersion" value="3.0.40624.0" />
    <param name="autoUpgrade" value="true" />
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
        <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
    </a>
</object>
         
Step 9: Run the application and enter the filtered string into the textbox. This data will be passed through the channel to the receiver application and this application will show patient details in the datagrid of the other XAP file as below:
DataGrid
Start entering patient name in it and the following output will be displayed:
Output
Conclusion: Using LocalConnection API, Silverlight 3 has provided a cool feature for sharing data across XAPs hosted on the same .aspx page. 
The entire source code of this article can be downloaded over here
If you liked the article,  Subscribe to the RSS Feed or Subscribe Via Email

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

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 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 eBook 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 .NET Standard and the upcoming C# 8.0 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!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years 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). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Jason moore on Sunday, February 21, 2010 1:17 PM
Quality stuff! thanks for sharing

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

C# .NET BOOK

C# Book for Building Concepts and Interviews

Tags

JQUERY COOKBOOK

jQuery CookBook