How can I pass a JavaScript function to Silverlight?

邮差的信 提交于 2019-12-06 08:42:48

问题


I'm evaluating the JavaScript/Silverlight interop capabilities and have been able to create a Silverlight instance using JavaScript and call methods on it. However, I now need a way of passing a JavaScript callback function to 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. 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)

回答1:


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. Then create a method that is marked as a ScriptableMember and takes a string that will be your passed in JavaScript method. I also added a method called InvokeCallback which will invoke the passed in javascript callback.

[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.

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




回答2:


There is a simpler way to pass Javascript function to Silverlight. All values from javascript can be represented by the ScriptObject type, this includes a function. Its for this reason that the ScriptObject has a InvokeSelf method.

You can create a property as simple as:-

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

Now lets say in Javascript we have this 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:-

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

Now in Silverlight code we can invoke this Callback with:-

Callback.InvokeSelf("Freed");



回答3:


Apparently, this does work if the using a delegate type of EventHandler (or EventHandler<>), but not for other delegate types.




回答4:


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


来源:https://stackoverflow.com/questions/6508195/how-can-i-pass-a-javascript-function-to-silverlight

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!