Как передать функцию JavaScript в Silverlight? - PullRequest
3 голосов
/ 28 июня 2011

Я оцениваю возможности взаимодействия JavaScript / Silverlight и смог создать экземпляр Silverlight, используя JavaScript и методы вызова для него. Однако теперь мне нужен способ передачи функции обратного вызова JavaScript в Silverlight.

Простая передача функции JavaScript методу 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)

Ответы [ 4 ]

2 голосов
/ 28 июня 2011

Не видя ваш код, я не могу сказать, что вы делаете неправильно, но я могу описать, что работало для меня в прошлом.

Со стороны 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 вы можете вызвать метод RegisterCallback, который вы определили в Silverlight, взяв объект silverlight на странице и вызвав метод с именем «silverlightInterop», которое мы зарегистрировали как имя нашего объекта сценариев.

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

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

Надеюсь, это поможет. У меня также есть некоторый пример кода, демонстрирующий это, который я написал некоторое время назад здесь

1 голос
/ 28 июня 2011

Существует более простой способ передачи функции Javascript в Silverlight.Все значения из javascript могут быть представлены типом ScriptObject, включая функцию.По этой причине у ScriptObject есть метод InvokeSelf.

. Вы можете создать свойство так же просто, как: -

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

Теперь давайте скажем, что в JavaScript у нас есть эта функция: -

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

Мы можем присвоить это свойству (предположим, что RegisterScriptableObject("Page", this) сделано) с помощью этого JS: -

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

Теперь в коде Silverlight мы можем вызвать этоОбратный звонок с: -

Callback.InvokeSelf("Freed");
0 голосов
/ 29 июля 2016

Мой код:

<!-- 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
0 голосов
/ 28 июня 2011

Очевидно, это работает, если используется тип делегата EventHandler (или EventHandler <>), но не для других типов делегатов.

...