Silverlight和Flash javascript桥接兼容性

时间:2010-12-23 19:57:55

标签: javascript silverlight flash

我正在为现有的Flash客户端开发Silverlight4替代品。我想保持与现有Flash HTML桥接javascript函数的兼容性,但我无法弄清楚如何直接在Silverlight客户端对象上公开javascript接口而不是包含对象。

在Flash中,可以直接在客户端对象上调用Bar(),如:

var flashClient = document.GetElementById(_currentFlashId);  
flashClient.Bar(); 

但是在Silverlight中,我还没有找到直接在Silverlight对象上调用接口的方法。相反,它似乎只能在包含的对象上公开接口,如:

var silverlightClient = document.GetElementById(_currentSilverlightId);
silverlightClient.Foo.Bar();

上面的“Foo”对象似乎是必需的,因为

RegisterScriptableObject("Foo", MyFooObject);
无法使用null第一个参数调用

所以,在Silverlight中,有没有办法只有:

silverlightClient.Bar();

2 个答案:

答案 0 :(得分:1)

如果您只是想要一个具有兼容接口的对象,您可以这样做:

var silverlightClient = document.GetElementById(_currentSilverlightId).Foo;

答案 1 :(得分:0)

有一种费力的方法可以做到这一点(我遇到了同样的情况 - 试图直接替换Flash应用程序的Silverlight)。

对于每个[ScriptableMember],请调用 BackBind 方法,在调用HtmlPage.RegisterScriptableObject("Foo", MyFooObject);之后使用参数数量

BackBind方法:

void BackBind(string methodName, int argCount) {
    var id = HtmlPage.Plugin.Id;
    var sb = new StringBuilder();
    sb.Append("var x = document.getElementById('");
    sb.Append(id);
    sb.Append("'); x.");
    sb.Append(methodName);
    sb.Append(" = function(");

    for (int i = 0; i < argCount; i++) {
        if (i > 0) sb.Append(',');
        sb.Append((char)('A' + i)); // if you have more than 26 arguments, improve this!
    }

    sb.Append("){return x.content.");
    sb.Append(ScriptRegistration);
    sb.Append(".");
    sb.Append(methodName);
    sb.Append("(");

    for (int i = 0; i < argCount; i++) {
        if (i > 0) sb.Append(',');
        sb.Append((char)('A' + i)); // if you have more than 26 arguments, improve this!
    }

    sb.Append(");};");
    HtmlPage.Window.Eval(sb.ToString());
    // calls something like:  var x = document.getElementById('my_id'); x.Bar = function(a,b){return x.content.Foo.Bar(a,b);};
}

用法示例:

public class MyFooObject {
    const string ScriptRegistration = "Foo";
    public MyFooObject () {
        HtmlPage.RegisterScriptableObject(ScriptRegistration, this);
        BackBind("Bar", 2);
        BackBind("Baz", 0);
    }

    [ScriptableMember]
    public void Bar(string a, int b) { /* stuff */ }

    [ScriptableMember]
    public string Baz() { return "stuff"; }
}

希望有所帮助!