Question

I am creating a Silverlight application which will be heavily javascripted against.

To enable JS interaction, I have created the following SL class:

[ScriptableType]
public class JavaScriptProxy
{
    private string _version;

    // provided for testing SL-JS integration
    [ScriptableMember]
    public void SmokeTest() { HtmlPage.Window.Alert("Hello world!"); }
}

And loaded it on the constructor of the main SL application:

public App()
{
    this.Startup += this.onStartup;
    this.Exit += this.Application_Exit;
    this.UnhandledException += this.Application_UnhandledException;

    InitializeComponent();

    // register javascript bridge proxy
    // (must register in constructor so proxy is available immediatly)
    HtmlPage.RegisterScriptableObject("JsProxy", new JavaScriptProxy());
}

However, as this is a Javascript-heavy app, it must be loadable via javascript itself.

I.e. something alongs:

// called on body.onLoad
function init() {

    var proxy;

    var el = document.getElementById("target_canvas");

    Silverlight.createObject(..., el, "agApp" ..., {

        onLoad: function() {
            proxy = agApp.Content.JsProxy;

            // ***this line is ok***
            proxy.SmokeTest();
        }

    });        

    // ***this line fails (of course)***
    proxy.SmokeTest();

}

However, this raise the error because agApp.Content.JsProxy is not available fully until the Silverlight onLoad event is fired, thus the JsProxy field is unavailable.

How can I enable access to the JsProxy class immediately as I create the Silverlight instance? Some thing alongs while(_mutex); is probably a bad idea.

I had to this because there will be another layer of abstraction building on the creation of Silverlight app instances, so that function must synchronously load all SL contents in one go.

Was it helpful?

Solution

This is due to Silverlight and JavaScript are operating on seperate threads. Even though you've requested the browser to load the said Silverlight control, it doesn't wait around for Silverlight to finish loading before it proceeds to the next line.

You can only access the JS Proxy after Silverlight has instantiated it so you can either wait for the OnLoad event to fire (but this will only fire after the entire Silverlight.xap is fully loaded) that or after you RegisterScriptableObject fire a JavaScript method called onYourJSProxyNameLoaded() which will put you back inline with the workflow you desire.

HTH.

- Scott Barnes / Rich Platforms Product Manager / Microsoft.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top