我正在评估JavaScript / Silverlight互操作功能,并且能够使用JavaScript和调用方法创建一个Silverlight实例。但是,我现在需要一种将JavaScript回调函数传递给Silverlight的方法。
简单地将JavaScript函数传递给期望Action的Silverlight方法不起作用,尽管错误表明它的意图。我错过了什么?例外情况:
Microsoft JScript runtime error: System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
at System.Windows.Hosting.ScriptingInterface.GetDelegateForScriptObject(Type eventHandlerType, ScriptObject obj)
at System.Windows.Browser.ScriptObject.ConvertTo(Type targetType, Boolean allowSerialization)
at System.Windows.Hosting.ScriptingInterface.GetScriptParamValueForType(ScriptParam scriptParam, Type desiredType)
at System.Windows.Hosting.ScriptingInterface.ConvertFromScriptParams(ParameterInfo[] parameters, ScriptParam[] args)
at System.Windows.Browser.ManagedObjectInfo.ScriptMethod.Invoke(ManagedObject obj, InvokeType invokeType, ScriptParam[] args)
at System.Windows.Browser.ManagedObjectInfo.Invoke(ManagedObject obj, InvokeType invokeType, String memberName, ScriptParam[] args)
at System.Windows.Hosting.ManagedHost.InvokeScriptableMember(IntPtr pHandle, Int32 nMemberID, Int32 nInvokeType, Int32 nArgCount, ScriptParam[] pArgs, ScriptParam& pResult, ExceptionInfo& pExcepInfo)
答案 0 :(得分:2)
如果没有看到你的代码,我就不能说你做错了什么,但我可以描述一下过去对我有用的东西。
在Silverlight端,您需要将类注册为可编写脚本的对象。然后创建一个标记为ScriptableMember的方法,并获取一个将在JavaScript方法中传递的字符串。我还添加了一个名为InvokeCallback的方法,它将调用传入的javascript回调。
[ScriptableType]
public partial class Page : UserControl
{
private string jsCallback;
public Page()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("silverlightInterop", this);
}
[ScriptableMember]
public void RegisterCallback(string callback)
{
jsCallback = callback;
}
public boid InvokeCallback(string arg)
{
if(!string.IsNullOrEmpty(jsCallback))
{
System.Windows.Browser.HtmlPage.Window.Invoke(jsCallback, arg);
}
}
}
在JavaScript方面,您可以通过抓取页面上的silverlight对象并调用名为“silverlightInterop”的方法调用您在Silverlight中定义的RegisterCallback方法,该方法已注册为我们的可编写脚本对象的名称。
function jsCallback(someArg) {
alert(someArg);
}
var silverLightControl = document.getElementById("silverlightControl");
silverLightControl.content.silverlightInterop.RegisterCallback("jsCallback");
我希望这会有所帮助。我还有一些示例代码演示了我之前写过的here
答案 1 :(得分:1)
有一种更简单的方法可以将Javascript函数传递给Silverlight。来自javascript的所有值都可以用ScriptObject
类型表示,这包括一个函数。因此ScriptObject
有一个InvokeSelf
方法。
您可以创建一个简单的属性: -
[ScriptableMember]
public ScriptObject Callback { get; set; }
现在让我们在Javascript中说我们有这个功能: -
function sayHello(name)
{
alert("Hello " + name);
}
我们可以使用这个JS将它分配给属性(假设RegisterScriptableObject("Page", this)
已经完成): -
document.getElementById("mySL").Content.Page.Callback = sayHello;
现在,在Silverlight代码中,我们可以使用以下命令调用此回调: -
Callback.InvokeSelf("Freed");
答案 2 :(得分:0)
显然,如果使用委托类型的EventHandler(或EventHandler<>),而不是其他委托类型,则可以使用。
答案 3 :(得分:0)
我的代码:
<!-- language: JavaScript -->
function sendText() {
return "Hi from Javascript!";
}
<!-- language: C# -->
string obj = HtmlPage.Window.Invoke("sendText", null) as string;
txtReturnData.Text = obj;
<!-- language: VB.Net -->
Dim obj As String = TryCast(HtmlPage.Window.Invoke("sendText", Nothing), String)
txtReturnData.Text = obj