我认为使用 Windows 窗体 WebBrowser 控件是您最好的选择。为此,您需要将 Silverlight 应用程序放在网页上,然后将 WebBrowser 指向页面的 URI。
为了防止您的 WebBrowser 控件表现得像 IE,我建议设置以下内容:
webBrowser.AllowNavigation = false;
webBrowser.AllowWebBrowserDrop = false;
webBrowser.IsWebBrowserContextMenuEnabled = false;
webBrowser.WebBrowserShortcutsEnabled = false;
从 Silverlight 中调用表单上的方法非常容易。首先,您需要一个包含您想从 Silverlight 调用的所有方法的类。您可以使用表单本身或其他对象,但您需要使用 [ComVisible(true)] 属性标记类。然后将对象分配给 WebBrowser.ObjectForScripting 属性。这会将您的对象公开为网页上的“window.external”。
[ComVisible(true)]
public partial class Form1 : Form
{
......
webBrowser.ObjectForScripting = this;
......
public void CallMeInForm(string something)
{
MessageBox.Show("Silverlight said: " + something);
}
}
在您的 Windows 窗体项目中就是这样。在您的 Silverlight 应用程序中,您需要获取此 ObjectForScripting 并在其上调用方法。要调用上面示例中的方法,请使用以下行:
using System.Windows.Browser;
......
ScriptObject myForm = (ScriptObject)HtmlPage.Window.GetProperty("external");
myForm.Invoke("CallMeInForm", "testing 1 2 3");
Invoke 命令允许您将任意数量和类型的参数传递给您的函数,尽管我怀疑如果您尝试传递复杂的数据类型,它不会非常喜欢它。但如果你需要这样做,你总是可以使用序列化。
从您的表单中调用 Silverlight 函数似乎是一个更狡猾的方向。我还没有完全弄清楚这一点。
在您的 Silverlight 应用程序中,您还可以向网页公开函数。为此,请使用 HtmlPage.RegisterScriptableObject() 函数。同样,您可以使用要公开的方法传入任何类。但是,对于要公开的方法,您必须使用 [ScriptableMember] 属性对其进行标记。
HtmlPage.RegisterScriptableObject("Page", this);
......
[ScriptableMember]
public void CallMeInSilverlight(string message)
{
HtmlPage.Window.Alert("The form said: " + message);
}
此时,您的方法在页面上暴露给 JavaScript,您可以这样调用它,假设您将 id="silverlightControl" 添加到您的 <object> 元素:
document.getElementById('silverlightControl').Content.Page.CallMeInSilverlight("testing 1 2 3");
注意到Page 属性了吗?这就是对RegisterScriptableObject() 的调用给我们的。现在,让我们把它包装成一个整洁的 JavaScript 方法:
<script type="text/javascript">
function CallMe(message) {
var control = document.getElementById('silverlightControl');
control.Content.Page.CallMeInSilverlight(message);
}
</script>
现在我们可以从 Windows 窗体应用程序中调用 CallMe() 方法,如下所示:
public void CallToSilverlight()
{
webBrowser.InvokeScript("CallMe", new object[] { "testing 1 2 3" });
}