【发布时间】:2014-02-03 23:59:42
【问题描述】:
我正在用 C# 创建一个应用程序,它为大多数 GUI 托管自定义网页。作为宿主,我想提供一个javascript API,以便嵌入的网页可以访问宿主应用程序提供的一些服务。
我已经能够使用 WebBrowser.ObjectForScripting 属性和实现一个脚本类来获得这个工作的简单案例。这适用于同步 javascript 调用。但是,主机提供的一些操作是长时间运行的,我想提供在操作完成时回调 javascript 的能力。这就是我遇到麻烦的地方。
Javascript:
function onComplete( result )
{
alert( result );
}
function start()
{
window.external.LongRunningProcess( 'data', onComplete );
}
C#:
[ComVisible(true)]
public class ScriptObject
{
public void LongRunningProcess( string data, <???> callback )
{
// do work, call the callback
}
}
javascript 中的“开始”功能启动了整个过程。我遇到的问题是,回调的类型是什么?我应该如何从 C# 调用它?
如果我使用字符串类型进行回调,它会编译并运行,但在 LongRunningProcess 方法中,回调实际上包含 onComplete 函数的全部内容(即'function onComplete(result){alert(result)}')
如果我使用对象类型,它会作为 COM 对象返回。使用 Microsoft.VisualBasic.Information.TypeName 方法,它返回“JScriptTypeInfo”。但据我所知,这不是一个真正的类型,也没有在整个 MSDN 中真正提及它。
如果我使用 IReflect 接口,它可以正常运行,但是我找不到对象上的任何成员、字段或属性。
解决方法是传递回调函数的字符串名称而不是函数本身(即 window.external.LongRunningProcess( 'data', 'onComplete' ); )。我确实知道如何按名称执行 javascript 函数,但我宁愿在网页中不需要该语法,它也不适用于 javascript 中的内联回调定义。
有什么想法吗?
不管怎样,我已经让这个系统与 Chromium Embedded 框架一起工作,但我正在努力将代码移植到 WebBrowser 控件以避免重新分发 Chromium 的庞大规模。然而,正在开发的 HTML 页面最终将在 Linux/Mac OSX 上运行,而 Chromium 可能仍会被使用。
【问题讨论】:
-
我不是 C# 中的程序员...也许这不是您问题的解决方案,但我的同事使用库来执行 C# 中的 JS(我不记得是否 C#或 .net)可能对您没用,但您尝试查看:javascriptdotnet.codeplex.com。或者你可以传递
callback像字符串window.external.LongRunningProcess( 'data', 'onComplete');并且在c# 中你可以使用这个名称创建一个函数并像回调一样执行它而不使用C# 中的JS 函数(但使用本机C# 函数)...如果注释不是'无法帮助您,很抱歉耽误您的时间
标签: c# javascript callback webbrowser-control