2011-02-08 36 views
1

我有一個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對象。好吧,它不能被視爲動態的,但它是什麼?如何調用它的任何方法?

回答

2

有沒有在這個時間管理,只有互操作。您提到的兩個選項(DOM橋接上的JavaScript互操作,或COM託管)都是存在的。

我讚揚你做你的研究 - 當我點擊這個問題時,你知道我要說的一切!

0

我不完全確定如何在SL應用程序和主機之間傳遞複雜的結構,但是您可能在提高事件時選擇的一個選項是通過URL傳遞信息。將事件處理程序附加到WebBroswer.Navigated事件,並讓該處理程序根據url中的信息提升主機的事件。

例如,我們有一個託管在WPF WebBrowser控件內的Silverlight應用程序。我們想知道用戶何時點擊Silverlight應用程序中的「關閉」按鈕。我們附加了一個事件處理程序到WebBrowser.Navigated並解析了URL。我們特別在該網址中查找「closed = true」。如果找到,關閉整個應用程序(包括WPF主機)。

Silverlight App inside WPF WebBrowser ?

+0

謝謝,這很好,但我需要主機和SL應用程序之間的溝通。 – Shrike 2011-02-08 15:56:31

相關問題