Attention: We are retiring the ASP.NET Community Blogs. Learn more >

Calling Silverlight managed code (C#) from the client-side (Javascript)

Even though we write managed code to build Silverlight apps, it all exists on the client side, so we need to be able to have html and Silverlight interact without hitting the server-side.  This is built into Silverlight 2, and is very similar to exposing C# web service calls to the client using ASP.net AJAX... only we never have to make calls to the server.To provide a quick example, I'll create a simple Silverlight object that contains only a TextBox and show how it can be updated from Javascript.  I'll create an html text box that updates my silverlight object's TextBox while I type.  So in my html test page, I'll add an <input/> right above the generated code for the Silverlight object.  Before I write client side functionality, I want to setup my Silverlight code to accept commands from Javascript.  First, the Xaml:

<UserControl x:Class="JStoManagedCode.Page" xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width="400" Height="300">   
   
<Grid x:Name="LayoutRoot" Background="White">
        <TextBlock x:Name="SilverlightText"></TextBlock>
    </Grid>
</UserControl>

Next, in my code behind for the root visual (Page.xaml.cs), I’ll need to:
    a)      Make the class a scriptable type, and register it in the html page
   
b)      Create a function to update the Silverlight text, and expose it to the client.

To make the class scriptable, I need to add a [ScriptableType] attribute to the class declaration (System.Windows.Browser namespace).  Then I’ll register the class to the client by calling HtmlPage.RegisterScriptableObjectThen I’ll write a function that updates the Silverlight object, and will add a [ScriptableMember] attribute to that function.  Here’s what the final code looks like:

using System.Windows.Controls;
using System.Windows.Browser; 

namespace JStoManagedCode
{
      [ScriptableType]
      public partial class Page : UserControl
      {
            public Page()
            {
                  InitializeComponent();
                  HtmlPage.RegisterScriptableObject("SilverlightTextSample", this);
            }
            [ScriptableMember]
            public void UpdateSilverlightText(string newText)
            {
                  SilverlightText.Text = newText;
            }
      }
}

Now my Silverlight object is ready to accept calls to UpdateSilverlightText via Javascript!  Let’s call it.In my Html page, I’ll add a textbox (input) above the silverlight object add an event handler to the textbox’s onkeypress event:

    <input id="clientTextBox" onkeypress="clientTextChanged(event)" />

     <!-- Runtime errors from Silverlight will be displayed here.
      This will contain debugging information and should be removed or hidden when debugging is completed -->
     <div id='errorLocation' style="font-size: small;color: Gray;"></div>
     <div id="silverlightControlHost">
            <object id="silverlightObject" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%">
                  <param name="source" value="ClientBin/JStoManagedCode.xap"/>
                  <param name="onerror" value="onSilverlightError" />
                  <param name="background" value="white" />
                      <a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
                      <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   
                  </a>
            </object>
            <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
    </div>

Finally I’ll write the Javascript event handler that in turn calls my Silverlight function:

function clientTextChanged ( e ) {
      var newText = document.getElementById("clientTextBox").value;
      var silverlightObject = document.getElementById("silverlightObject");
      var keynum;      if ( window.event ) {  // IE
            keynum = e.keyCode;
      }
      else if ( e.which ) {  // Other browsers
            keynum = e.which;
      }
      newText += String.fromCharCode(keynum);
 
      silverlightObject.content.SilverlightTextSample.UpdateSilverlightText(newText);
}

And here’s how it all looks (aplogies for the screenshot, I'm unable to post Xap files):

3 Comments

  • very good

  • Does not seem to work in FF3 - although fine IE7
    silverlightObject.content.SilverlightTextSample returns null

    Any ideas ?

  • Mike - I'm not having a problem with FF3. &nbsp;It's been awhile since you posted your comment, so you might want to try again with the released version of Silverlight. &nbsp;Otherwise I don't see anything in particular that would be browser-sensitive in the javascript.If silverlightObject.content is not null, your Silverlight object reference is correct.&nbsp; Make sure you have the [ScriptableType] Attribute set on the Page class, and your constructor registers the object in your page.&nbsp; Again, these are things that would break IE if there were missing as well, so hopefully it's just a resolved bug from Beta.

Comments have been disabled for this content.