我正在为现有的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();
答案 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"; }
}
希望有所帮助!