简体   繁体   English

如何将 JavaScript function 传递给 Silverlight?

[英]How can I pass a JavaScript function to Silverlight?

I'm evaluating the JavaScript/Silverlight interop capabilities and have been able to create a Silverlight instance using JavaScript and call methods on it.我正在评估 JavaScript/Silverlight 互操作功能,并且已经能够使用 JavaScript 创建一个 Silverlight 实例并在其上调用方法。 However, I now need a way of passing a JavaScript callback function to Silverlight.但是,我现在需要一种将 JavaScript 回调 function 传递给 Silverlight 的方法。

Simply passing a JavaScript function to a Silverlight method expecting an Action doesn't work although the error suggest that it's intended to.只需将 JavaScript function 传递给期望操作的 Silverlight 方法不起作用,尽管错误表明它是有意的。 What am I missing?我错过了什么? The exception details:异常详情:

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)

Without seeing your code I cannot say what you are doing wrong but I can describe what has worked for me in the past.如果没有看到你的代码,我不能说你做错了什么,但我可以描述过去对我有用的东西。

On the Silverlight side you need to register a class as a scriptable object.在 Silverlight 端,您需要将 class 注册为可编写脚本的 object。 Then create a method that is marked as a ScriptableMember and takes a string that will be your passed in JavaScript method.然后创建一个标记为 ScriptableMember 的方法,并采用一个字符串,该字符串将作为您在 JavaScript 方法中传递的字符串。 I also added a method called InvokeCallback which will invoke the passed in javascript callback.我还添加了一个名为 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);
      }
    }
}

On the JavaScript side you can call the RegisterCallback method that you defined in Silverlight by grabbing the silverlight object on the page and calling the method off of the name "silverlightInterop" which we registered as the name of our scriptable object. On the JavaScript side you can call the RegisterCallback method that you defined in Silverlight by grabbing the silverlight object on the page and calling the method off of the name "silverlightInterop" which we registered as the name of our scriptable object.

function jsCallback(someArg) {
   alert(someArg);
}

var silverLightControl = document.getElementById("silverlightControl");
silverLightControl.content.silverlightInterop.RegisterCallback("jsCallback");

I hope this helps.我希望这有帮助。 I also have some sample code the demonstrates this which I wrote a while ago here我也有一些示例代码演示了我不久前在这里写的

There is a simpler way to pass Javascript function to Silverlight.有一种更简单的方法可以将 Javascript function 传递给 Silverlight。 All values from javascript can be represented by the ScriptObject type, this includes a function. javascript 中的所有值都可以用ScriptObject类型表示,这包括 function。 Its for this reason that the ScriptObject has a InvokeSelf method.出于这个原因, ScriptObject有一个InvokeSelf方法。

You can create a property as simple as:-您可以创建一个简单的属性:-

 [ScriptableMember]
 public ScriptObject Callback { get; set; }

Now lets say in Javascript we have this function:-现在让我们说在 Javascript 我们有这个 function:-

function sayHello(name)
{
    alert("Hello " + name);
}

We can assign this to the property (assume the RegisterScriptableObject("Page", this) has been done) with this JS:-我们可以使用这个 JS 将它分配给属性(假设RegisterScriptableObject("Page", this)已经完成):-

document.getElementById("mySL").Content.Page.Callback = sayHello;

Now in Silverlight code we can invoke this Callback with:-现在在 Silverlight 代码中,我们可以调用此回调:-

Callback.InvokeSelf("Freed");

My Code:我的代码:

<!-- 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

Apparently, this does work if the using a delegate type of EventHandler (or EventHandler<>), but not for other delegate types.显然,如果使用 EventHandler(或 EventHandler<>)的委托类型,这确实有效,但不适用于其他委托类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM