5/15/2009

Silverlight: A few notes on HTML / JavaScript access from Silverlight

 

You can call into a Silverlight control from JavaScript in the HTML page and access Silverlight managed code properties and methods. The process is relatively straight forward really lets you use a Silverlight object as a true control, and not just a fancy animated advertisement (Sorry Flash designers…)

I will follow shortly with notes on the other half of the picture, accessing HTML objects and JavaScript functions from Silverlight code.

 

 

Accessing data / method in Silverlight from JavaScript

Step 1:  Add a reference

Add a reference to System.Windows.Browser, and add a using or Imports to your code file.

        using System.Windows.Browser;

 

Step2: Mark the item or class to be scriptable

The item can be either a property or a method. The attribute is [ScriptableMember] (<ScriptableMember> in VB.Net). Some examples show [ScriptableMemberAttribute], but the short form is preferred.

A sample property:

        private int x=9;

        [ScriptableMember]
        public int MyProperty { get { return x; } set { x = value; } }

 

The entire class can be marked as Scriptable using [ScriptableType], but note that all public members are then available for access from JavaScript.

See notes at the end of this article for more info on the use of the attributes.

 

Example:

or the entire class (warning: all publics are exposed)
[ScriptableType]
public class Calculator2
{
    public int Add(int a, int b)
       { return a + b; }

    public int Subtract(int a, int b)
    { return a – b; }
}

 

Step 3: Register the class as scriptable

Register the class as scriptable either in the app.xaml.cs, but more likely in yourpage.xaml.cs file.

Example if registered from Page.xaml

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            HtmlPage.RegisterScriptableObject("Page", this);

        }

Example to register another class:

         private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {

            HtmlPage.RegisterScriptableObject("MyPage",  new Class1());

        }

 

Step 4: Make the call from the HTML page:

This example makes the call from a button, but could also be done from the <BODY> onload event or the Siverlight control’s load event.

    <script>
    function GetSomeData() {
        sl = document.getElementById("Xaml1");
        alert(sl.Content.Page.MyProperty);
     }
    </script>
    <button onclick="GetSomeData()" >Get Data</button>

or as a single line:
        <button onclick="sl = document.getElementById('Xaml1');alert(sl.Content.Page.MyProperty);" >Get Data 2</button>

or even...
        <button value="Get Data" onclick="alert(document.getElementById('Xaml1').Content.Page.MyProperty);" >Get Data 2</button>

 

Some observations and discoveries…

  • Both attributes are not needed!
    Some sources say that both the class must be marked as [ScriptableType] and the property or method must be marked as [ScriptableMember]. I found that just marking the class as [ScriptableType] made all public members script accessible. I also found that marking a property or method as [ScriptableMember] was all that was needed to expose the one member. It was not necessary to mark up the class at all.

    And I would say that Microsoft agrees with me!  ;-)
    http://msdn.microsoft.com/en-us/library/system.windows.browser.scriptabletypeattribute(VS.95).aspx
  • “ScriptableTypeAttribute Class - Indicates that all public properties, methods, and events on a managed type are available to JavaScript code when they are registered by using the RegisterCreateableType method.”

    “If you want to expose only a subset of properties, methods, and events as scriptable endpoints, do not use a ScriptableTypeAttribute object. Instead, attribute the subset of properties, methods, and events with a ScriptableMemberAttribute object.”

    If you do choose to use [ScriptableType] and want to hide one of the public members mark it with:

       [ScriptableMember(EnableCreateableTypes = false)]

    Note: the preferred notation for the attributes excludes the word “Attribute”, so use [ScriptableType] and [ScriptableMember].

     

  • "HtmlAccess=Enabled" is not needed for calls INTO Silverlight, only to enable calls out.
      <asp:Silverlight ID="Xaml1" HtmlAccess=Enabled ...

 

Useful web resources:

No comments:

Note to spammers!

Spammers, don't waste your time... all posts are moderated. If your comment includes unrelated links, is advertising, or just pure spam, it will never be seen.