我有一个WPF应用程序。我需要在其中嵌入Silverlight应用程序。据我所知最常见的做法是使用System.Windows.Controls.WebBrowser控件(注意:我的应用程序是wpf而不是WinForms)。
顺便说一句:还有另一种方法来托管Silverlight应用程序 - 使用其COM接口(请参阅http://www.codeproject.com/KB/atl/Host_Silverlight_In_ATL.aspx)。.NET桌面应用程序内嵌的Silverlight应用程序和它们之间的通信
所以在我的WPF应用程序我有一个WebBrowser地方:
<WebBrowser x:Name="webBrowser">
,我加载我的HTML页面(假设本地HTLM页面简单起见):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
webBrowser.LoadCompleted += WebBrowser_LoadCompleted;
webBrowser.Navigate(new Uri(Path.GetFullPath("HostPage.htm")));
}
private void WebBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
MessageBox.Show("Silverlight app has loaded");
}
确定。这很容易。
现在我想通过SL应用程序和来自主机的SL应用程序与主机进行通信。
我理解HTML(JS)和Silverlight(http://msdn.microsoft.com/en-us/library/cc645076%28VS.95%29.aspx)之间以及.NET和JS内部WebBrowser之间的互操作性的技术。
我可以用一个对象(用ComVisibleAttribute标记)设置WebBrowser.ObjectForScripting并且该对象将在JS中访问。
我甚至可以从我的嵌入式Silverlight应用程序获得参考这个对象:
(ScriptObject) HtmlPage.Window.GetProperty("external");
我也可以让Silverlight应用程序到JS可见(可能举办的代码)通过HtmlPage.RegisterScriptableObject里面的一些对象(“名“, 一个东西);
但是。问题是,在所有情况下,我必须处理一些无类型的ScriptObject实例。 但我想在主机和SL-app之间建立“完全托管的代码”通信。我的意思是传递复杂的结构/类/代表,提高事件等等,即没有任何“无类型的JS东西”。
我该怎么做?
UPDATE: 好吧,似乎没有好方法来做我想做的事。 所以我必须处理JS-互操作性。但在这里我有一个问题。 从主机设置ObjectForScripting和SL-app可以使用它。这意味着SL-应用从WebBrowser.ObjectForScripting建立对象的方法得到的结果:
((ScriptObject) HtmlPage.Window.GetProperty("external")).Invoke("methodName")
但不是相反。 在我的SL-程序,我注册(类型BridgeSl)对象:
m_bridgeSl = new BridgeSl();
HtmlPage.RegisterScriptableObject("bridge", m_bridgeSl);
然后在HTML创建JS-功能:
<script type="text/javascript">
var g_bridgeSl = null;
function pluginLoaded(sender, args) {
g_bridgeSl = sender.getHost().Content.bridge;
}
</script>
其中pluginLoaded是SL插件的onLoad事件的处理程序:
<object id="slCtrl" data="data:application/x-silverlight-2," type="application/x-silverlight-2" ...>
<param name="onLoad" value="pluginLoaded" />
</object>
然后加入函数返回这个对象:
function getBridge() {
return g_bridgeSl;
}
我做这一切的东西,我希望我能得到BridgeSl的情况下我的主机内部应用程序:
var bridgeSl = WebBrowser.InvokeScript("getBridge");
其实我得到的东西。这是“System .__ ComObject”的一个实例。但是当我把它强制转换为动态时:
dynamic dynBridgeSl = bridgeSl;
我得到带有消息“方法或操作未实现”的System.SystemException对象。好吧,它不能被视为动态的,但它是什么?如何调用它的任何方法?
谢谢,这很好,但我需要主机和SL应用程序之间的沟通。 – Shrike 2011-02-08 15:56:31