DCSIMG
Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight - Alex Golesh's Blog About Silverlight Development

Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

Lately I've been asked couple of times about catching managed events in JavaScript and catching JavaScript events in Silverlight managed code.

In fact it is very easy, but seems not so obvious... Here it goes.

To catch JavaScript event in Silverlight managed code, all your application need to do is to "attach" to event from some HtmlElement you have on hosting page and define some managed EventHandler to handle the event.

Sample page as it was auto generated by Visual Studio 2008, MyApplicaitionTestPage.html. All I added to this test case is HTML button:

   1: <input id="Button1" type="button" value="Test"/></p>

Now, in my code behind class I defined function, which will handle the event:

   1: void JsButtonEventHandler(object sender, EventArgs e)
   2: {
   3:     //Just prints notification in some TextBlock
   4:     txtOutput.Text += "Got event from = " + (sender as HtmlElement).Id.ToString() + "\n";
   5: }

and subscribed to HTMLElement event. This could be done anywhere in code; I did it in class constructor:

   1: //Class ctor
   2: public Page()
   3: {
   4:     InitializeComponent();
   5:     
   6:     //Subscribe to event 'onclick' 
   7:     HtmlPage.Document.GetElementById("Button1").AttachEvent("onclick", new EventHandler(JsButtonEventHandler)); 
   8: }

That's it - now we can receive events from HTML elements in our Silverlight application

image image

Now let's extend this sample, and subscribe in JavaScript to some events from Silverlight.

First of all, I need to put "[ScriptableType]" attribute to my class and "[ScriptableMember]" attribute to my event. Actually, I need to put "[ScriptableType]" attribute to all data types I'd like to work with in JavaScript. Then I need to register the instance to be accessible from script.

Last thing I'm doing in this sample is events fire as a reaction on Silverlight mouser click event.

Here is my my super simple XAML page:

   1: <UserControl x:Class="SilverlightApplication7.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     Width="400" Height="300">
   5:     <Grid x:Name="LayoutRoot" Background="Yellow">
   6:         <TextBlock x:Name="txtOutput" Width="400" Height="300"/>
   7:         <Button Content="test" Width="100" Height="25" Click="Button_Click"/>
   8:     </Grid>
   9: </UserControl>

And here is my complete class:

   1: //Register whole type as accessible from script
   2: [ScriptableType]
   3:  public partial class Page : UserControl
   4:  {
   5:      //Register the custom event to be as accessible from script
   6:      [ScriptableMember]
   7:      public event EventHandler<CustomEventHandler> ServiceCallFinished;
   8:  
   9:      //Register the simple event to be as accessible from script
  10:      [ScriptableMember]
  11:      public event EventHandler SomeEvent;
  12:  
  13:      public Page()
  14:      {
  15:          InitializeComponent();
  16:  
  17:          //Register this instance to be accessible from script
  18:          HtmlPage.RegisterScriptableObject("SilverlightApp", this);
  19:  
  20:          HtmlPage.Document.GetElementById("Button1").AttachEvent("onclick", new EventHandler(JsButtonEventHandler));
  21:      }
  22:  
  23:      private void Button_Click(object sender, RoutedEventArgs e)
  24:      {
  25:          //Fire test events on Silverlight button click
  26:          FireEvent("Test Event from Silverlight");
  27:          FireSimpleEvent();
  28:      }
  29:  
  30:      private void FireEvent(string output)
  31:      {
  32:          if (null != ServiceCallFinished)
  33:              ServiceCallFinished(this, new CustomEventHandler() { WCF_Output = output });
  34:      }
  35:  
  36:      private void FireSimpleEvent()
  37:      {
  38:          if (null != SomeEvent)
  39:              SomeEvent(this, new EventArgs());
  40:      }
  41:  
  42:      void JsButtonEventHandler(object sender, EventArgs e)
  43:      {
  44:          txtOutput.Text += "Got event from = " + (sender as HtmlElement).Id.ToString() + "\n";
  45:      }
  46:  }
  47:  
  48: //Class for sending custom event arguments
  49: [ScriptableType]
  50: public class CustomEventHandler : EventArgs
  51: {
  52:     public string WCF_Output { get; set; }
  53: }

Now let's see how I subscribe to those events in BLOCKED SCRIPT

I'm subscribing to "onload" event for Silverlight object, and in "onload" handler function subscribe to JavaScript events. Here is my Silverlight object DIV

   1: <div id="silverlightControlHost">
   2:     <p>WCF call results:</p>
   3:     <p><textarea id="TextArea1" cols="40" rows="5" width="400"></textarea></p>
   4:     <p>
   5:     
   6:     <input id="Button1" type="button" value="Test"/></p>
   7:     
   8:     <object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="50%" height="50%" id="SilverlightObject">
   9:         <param name="source" value="ClientBin/SilverlightApplication7.xap"/>
  10:         <param name="onerror" value="onSilverlightError" />
  11:         <param name="background" value="Gray" />
  12:         <param name="onload" value="OnLoaded" />
  13:         
  14:         <a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
  15:              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
  16:         </a>
  17:     </object>
  18:     <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
  19: </div>

and here is my JavaScript for OnLoaded function and event handler functions:

   1: function OnLoaded(sender, args)
   2: {
   3:     //Getting Silverlight object on page
   4:     var silverlightControlHost = document.getElementById("SilverlightObject");
   5:     //Subscribe to it events
   6:     silverlightControlHost.Content.SilverlightApp.ServiceCallFinished = ServiceCallFinished;
   7:     silverlightControlHost.Content.SilverlightApp.SomeEvent = SomeEvent;
   8: }
   9:  
  10: //General event handler function
  11: function SomeEvent(sender, e)
  12: {
  13:     alert("Some general Silverlight event received!");
  14: }
  15:  
  16: //Event handler for event with customized EventArgs 
  17: function ServiceCallFinished(sender, result)
  18: {
  19:     document.getElementById("TextArea1").value += "\n" + result.WCF_Output;
  20: }

The result works as expected:

image

I hope this covers all scenarios on how subscribe to events between HTML/JavaScript and Silverlight.

 

Enjoy,

Alex

Comments

# Silverlight Cream for July 28,2008 -- #337

Mark Monster on Mocking SL and Networking, Denislav Savkov inheriting from ItemsControl, Alex Golesh

Tuesday, July 29, 2008 2:41 AM by Community Blogs

# Websites tagged "textarea" on Postsaver

Pingback from  Websites tagged "textarea" on Postsaver

Saturday, October 11, 2008 11:47 AM by Websites tagged "textarea" on Postsaver

# re: Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

Thanks. Good On1!

Saturday, November 29, 2008 1:04 PM by Arrka

# re: Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

It would be nice to have this in VB as well...

Wednesday, June 03, 2009 12:51 PM by Roger

# re: Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

Awesome. Thanks for that.

Thursday, February 18, 2010 10:25 PM by Rana

# re: Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

This was a perfect explanation.

Wednesday, October 20, 2010 4:01 PM by Chris Anderson

# Result Works | AllGraphicsOnline.com

Pingback from  Result Works | AllGraphicsOnline.com

Wednesday, March 02, 2011 4:40 PM by Result Works | AllGraphicsOnline.com

# WebApp &amp; DeskApp Communication | [Ever]Evolving Software

Pingback from  WebApp &amp; DeskApp Communication | [Ever]Evolving Software

Saturday, April 09, 2011 11:06 PM by WebApp & DeskApp Communication | [Ever]Evolving Software

# re: Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

Hi Can you help in the following scenario. If i rather register the event on a button clicked it gets registered every time i click on the button. Therefore keep on adding every time I click on the button.

function ButtonClicked() {

                          var slControl = document.getElementById("silverlightControl");

                          if (slControl != null) {

                               var sLBridge = slControl.Content.SLBridge;

                               if sLBridge != null) {

                                   sLBridge.SaveDocumentCompleted = function () { alert("Saved"); };

                                   var saved = sLBridge.SaveDocument();

                               }

                          }

                       }

Friday, August 05, 2011 2:41 PM by Sanjay

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: