Silverlight在Winforms中托管

时间:2008-10-13 17:34:32

标签: c# javascript wpf winforms silverlight

我想通过winforms浏览器在winforms中托管一个silverlight控件,但是为了工作,我需要一些方法让表单与silverlight交谈,以及相反的方式。是否有可能以两种方式使用JavaScript作为中间人互相交互?即,让表单与浏览器的javascript说话,并让它与silverlight控件说话?有没有更好的办法?甚至是一种方式? (除了将代码编译为silverlight和wpf)

4 个答案:

答案 0 :(得分:15)

我认为使用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 Forms项目中的内容。在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" });
}

答案 1 :(得分:1)

看看Desklighter。不完全是你在寻找什么,但它确实证明它应该是可能的?

答案 2 :(得分:1)

如果您 所有需要做的只是在桌面应用中托管Silverlight,我建议您查看Jeremiah MorrillSilverlightViewport项目。它允许您在WPF或XNA应用程序中嵌入Silverlight应用程序。它仍然非常alpha,但你可能会发现它很有用。

这是一张让你胃口大开的图片:

http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=silverlightviewport&DownloadId=97946

答案 3 :(得分:0)

在winform应用程序中的Silverlight听起来像坏消息。这意味着你在一个应用程序中运行不同的CLR,并且必须处理许多增加的复杂性以使其工作。如果可能,请考虑在您的应用中使用完整的WPF,而不是link向您展示如何使用。