How to create Silverlight Object in the HTML-Interop



Introduction: Browser interoperability with Silverlight and vice versa has raised many possibilities for interesting interactions and use of javascipts in ways similar to their use in ASP.Net. Read previous article on this.

The problem with manipulating HTML element from Silverlight: is that it creates tightly bound code; in other words, a Silverlight application that has hard-coded assumptions about the HTML elements on the current page and their unique IDs., so when we changes these details in the HTML page, and the Silverlight codes for interacting with them won't work anymore.

Solution: is to allow interaction between codes, not elements. For example, Silverlight application can update the content of the HTML page by calling a JavaScript method that's in the page. This way, if the HTML elements on the page are ever changed, the JavaScript method can be updated to match at the same time and the Silverlight application won't need to be recompiled.

In a previous article (Read here) we have seen how to call browser scripts from Silverlight, with the help of a ScriptObject.

So in this article we will learn how to call Silverlight Methods from the Browser/HTML and also how to create silverlight class object. Before we start coding for it, let's theoretically understand the basic steps involved.

  1. Create a public method in Silverlight code that exposes the information or functionality we want the web page to use. We can place the method in our page class or in a separate class. We will need to stick to simple data types, like strings, Boolean values, and numbers, unless we want to go through the additional work of serializing your objects to a simpler form.
  2. Add the ScriptableMember attribute to the declaration of the method that we want to call from JavaScript.
  3. Add the ScriptableType attribute to the declaration of the class that includes the scriptable method.
  4. To expose your Silverlight method to JavaScript, call the HtmlPage.RegisterScriptableObject() method.

Step 1: Create a Silverlight Application and name it as "ScriptableSilverlight"
Step 2: We will create a Border and a TextBlock:

        <Border BorderThickness="1" BorderBrush="Green">
            <Border.Background>
                <LinearGradientBrush>
                <GradientStop Color="SteelBlue"></GradientStop>
                <GradientStop Color="White" Offset="1"></GradientStop>
            </LinearGradientBrush>               
           
</Border.Background>
            <TextBlock x:Name="txtBlock" Foreground="Black" TextWrapping="Wrap" Margin="5" FontFamily="Verdana"
                       Text="This is Silverlight TextBlock" FontSize="15"></TextBlock>                       
       
</Border>

Step 3: Next, in ScriptableSilverlightTestPage.html, i.e. in the project where our silverlght application is hosted. We are here because we choose this HTML to interop with.
Here we created two HTML paragraphs like below;

   
<p onclick="changeText()">Click Here To Change Text in Silverlight TextBlock</p>
    <p onclick="getRandom1To6()">Click here to get a random number from 1 to 6.</p>   

So the idea is to click over these paragraphs, invoke these methods and change Silverlight element.

The page should look like this:

silverlight1.gif

Step 4: In code behind we have this:

[ScriptableType]
    public partial class MainPage :
UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("Page", this);           
        }
        [ScriptableMember()]
        public void ChangeText(string newText)
        {
            txtBlock.Text = newText;
        } 
    }
[ScriptableMember()]
        public void ChangeText(string newText)
        {
            txtBlock.Text = newText;
        }

When registering a scriptable type, we need to specify a JavaScript object name and pass a reference to the appropriate object. Here, an instance of the ScriptableSilverlight class is registered with the name Page. This tells Silverlight to create a property named Page in the Silverlight control on the JavaScript page.

Thus, to call this method, the JavaScript code needs to find the Silverlight control, get its content, and then call its Page.ChangeText() method.
Here is the javascript function to call this method:

<script type="text/javascript">
         function changeText()
             {
             var control = document.getElementById("silverlightControl");
             control.content.Page.ChangeText("This TextBlock has been updated                  through JavaScript.");
         }

Note that in:
var control = document.getElementById("silverlightControl");"silverlightControl" is the ID of a silverlight object, which I have manually given here in the following line:

<object id="silverlightControl" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%" > 

You can trigger this JavaScript method at any time. Here's an example that fires it off when a paragraph is clicked:

<
p onclick="changeText()">Click Here To Change Text in Silverlight TextBlock</p>

Now, clicking the paragraph triggers the changeText() JavaScript function, which in turn calls the ChangeText() method that's a part of our ScriptableSilverlight class.

silverlight2.gif

Untill now we have seen how to call Silverlight method from HTML via javascripts. Won't it be super excited things to Instantiate silverlight class object in HTML.


As done before, we will write a class for generating a random number and mark declaration with [ScriptableType()], and create one method, and again to let javascript call it, we have marked it with [ScriptableMember()] declaration.

[ScriptableType()]
    public class
RandomNumbers
    {
        private Random random = new Random(); 
        [ScriptableMember()]
        public int GetRandomNumberInRange(int from, int to)
        {
            return random.Next(from, to + 1);
        }
    }

Previously, we needed to register this class to make it available to JavaScript code. However, instead of using the RegisterScriptableObject() method, we use the RegisterCreateableType() method, as shown here:

HtmlPage.RegisterCreateableType("RandomNumbers", typeof(RandomNumbers));

To create an instance of a registered type, we need to find the Silverlight control and call it's content.services.createObject() method. Below is a JavaScript function that displays a random number from 1 to 6 using an instance of the Silverlight RandomNumbers class:

function getRandom1To6() {
var control = document.getElementById("silverlightControl");
var random = control.content.services.createObject("RandomNumbers");
             alert("Your number is: " + random.GetRandomNumberInRange(1, 6));
         }

And in HTML, we call this javascript as:

<p onclick="getRandom1To6()">Click here to get a random number from 1 to 6.</p>
 
silerlight3.gif

So we learned how we can interop between Silverlight and HTML pages.

Hope this article do some needful for you.

Cheers.


Similar Articles