One thing that has really played on my mind since I started dabbling with Silverlight has been that all of my interactions with the app are just happening within the Silverlight application embedded onto a ASP.NET web page (other flavours are available) . What would happen if I wanted to make the Silverlight pass data back to the containing page to say change a header or navigate to a new URL, so that we can have a cool Silverlight based navigation structure.

So with out further anticipation I will show just how easy it is to get the Silverlight and ASP.NET page communicating, with just a little sprinkle of JavaScript magic.

Silverlight to ASP.NET

To show Silverlight communicating with the ASP.NET site it is hosted within I have just set up a new Silverlight application and inserted a text box and a button, when  I click the button I am wanting the Silverlight to change the property of the htmlText on the host page, to show the text entered in Silverlight.

First I must make sure that on the host (BlogDemo01TestPage.aspx) there is a item with the correct ID, here I have just used a header with ellipses.

   1: <h3 id="htmlText">...</h3>

This is then used from the Silverlight code behind file to reference the object, so we can change the text. As we are wanting to talk via the browser to the ASP.NET page we must first add a new reference to the browser. Then with the Click event of the SL button.

 

   1: using System.Windows.Browser;
   2:  
   3: namespace BlogDemo01
   4: {
   5:  
   6:     public partial class Page : UserControl
   7:     {
   8:         public Page()
   9:         {
  10:             ...
  11:         }
  12:  
  13:         private void Button_Click(object sender, RoutedEventArgs e)
  14:         {
  15:             HtmlPage.Document.GetElementById("htmlText").SetProperty("innerText",
  16:                                                               this.textBox.Text);
  17:         }
  18:     }
  19: }

This gets the element within the ASP.NET page with the ID of htmlText and replaces the innerText with that of what we entered in the SL text box.

 

htmlSL2 

ASP.NET to Silverlight

Now that we can successfully use Silverlight to communicate with the ASP.NET page we really would like it to happen in the opposite direction as well.

I first placed a blank http button onto the ASP.NET page which will now be used to try and raise an event within the Silverlight app, first we will have to create a JavaScript function within the web page which can call methods in the code behind.

   1: <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">
   2: <head runat="server">
   3:     <title>BlogDemo01</title>
   4: </head>
   5: <body style="height:100%;margin:0;">
   6:     <script language="javascript" type="text/javascript">
   1:  
   2:         function htmlButtonClick() 
   3:         {
   4:             var app = document.getElementById("Xaml1").Content.BlogDemo01;
   5:  
   6:             app.htmlClick();   
   7:         }
   8:     
</script>
   7:     <form id="form1" runat="server" style="height:100%;">
   8:         <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
   9:         <div>
  10:             <asp:Silverlight ID="Xaml1" Source="~/ClientBin/BlogDemo01.xap" 
  11:              runat="server" MinimumVersion="2.0.31005.0" Width="200" Height="200"/>
  12:         </div>
  13:         <h3 id="htmlText">...</h3>
  14:         
  15:         <button onclick="htmlButtonClick();" />
  16:     </form>
  17: </body>
  18: </html>

As you can see the code is now set up to call a method within the Silverlight page, which signature accepts no arguments and returns void.

All we need to do now is add the method to the Page.xaml.cs file and make a few tweaks to the class so that it can be accessed by the JavaScript. To do this we must make the class a scriptable type and the method we want to call a scriptable member.

 

   1: namespace BlogDemo01
   2: {
   3:     [ScriptableType]
   4:     public partial class Page : UserControl
   5:     {
   6:         public Page()
   7:         {
   8:             InitializeComponent();
   9:  
  10:             HtmlPage.RegisterScriptableObject("BlogDemo01", this);
  11:         }
  12:  
  13:         ...
  14:  
  15:         [ScriptableMember]
  16:         public void htmlClick()
  17:         {
  18:             this.textBox.Text = "Hello, World! from html.";
  19:         }
  20:     }

If we now run the application we can see that clicking the new button on the web page will call the JavaScript function which will in turn call the C# method in the XAML code behind file (told you we would use some JavaScript magic).

htmlSL1