C# 托管在 Winforms 中的 Silverlight

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/198360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:40:21  来源:igfitidea点击:

Silverlight Hosted in Winforms

c#javascriptwpfwinformssilverlight

提问by NotDan

I would like to host a silverlight control in winforms via a winforms browser, but for it to work I need some way for the forms to talk to the silverlight, and also the other way around. Would it be possible to somehow have the two interact with each other using JavaScript as a middleman? I.e., have the form speak to the browser's javascript, and have that speak to the silverlight control? Is there a better way? Or even a way at all? (other than compiling the code as silverlight and wpf)

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

采纳答案by wahrhaft

I think using the Windows Forms WebBrowser control is your best bet. To do this, you'll need your Silverlight app on a webpage, then you point your WebBrowser at the page's URI.

我认为使用 Windows Forms WebBrowser 控件是您最好的选择。为此,您需要在网页上使用 Silverlight 应用程序,然后将 WebBrowser 指向该页面的 URI。

To keep your WebBrowser control from acting like IE, I'd recommend setting the following:

为了防止您的 WebBrowser 控件表现得像 IE,我建议设置以下内容:

webBrowser.AllowNavigation = false;
webBrowser.AllowWebBrowserDrop = false;
webBrowser.IsWebBrowserContextMenuEnabled = false;
webBrowser.WebBrowserShortcutsEnabled = false;

Calling methods on your form from within Silverlight is easy enough to do. To start, you need a class that has all the methods you want to call from Silverlight. You can use your form itself or another object, but you need to mark the class with the [ComVisible(true)] attribute. Then you assign your object to the WebBrowser.ObjectForScripting property. This exposes your object as "window.external" on the webpage.

从 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);
    }
}

That's it for inside your Windows Forms project. Inside of your Silverlight app, you need to pick up this ObjectForScripting and invoke methods on it. To call the method in my example above, use the following lines:

这就是您的 Windows 窗体项目中的内容。在您的 Silverlight 应用程序中,您需要选择这个 ObjectForScripting 并调用它的方法。要调用上面示例中的方法,请使用以下几行:

using System.Windows.Browser;
......
ScriptObject myForm = (ScriptObject)HtmlPage.Window.GetProperty("external");
myForm.Invoke("CallMeInForm", "testing 1 2 3");

The Invoke command lets you pass any number and type of parameters to your function, although I suspect it wouldn't like it very much if you try passing complex datatypes around. But if you needed to do so, you could always use serialization.

Invoke 命令允许您将任意数量和类型的参数传递给您的函数,尽管我怀疑如果您尝试传递复杂的数据类型它不会很喜欢它。但是如果你需要这样做,你总是可以使用序列化。

Calling Silverlight functions from your form seems to be the tricker direction. I haven't figured this one out completely yet.

从您的表单调用 Silverlight 函数似乎是更巧妙的方向。我还没有完全弄清楚这一点。

In your Silverlight app, you also expose functions to the webpage. To do this, use the HtmlPage.RegisterScriptableObject() function. Again, you can pass in any class with methods you want to expose. For a method to be exposed, though, you have to mark it with the [ScriptableMember] attribute.

在您的 Silverlight 应用程序中,您还可以向网页公开函数。为此,请使用 HtmlPage.RegisterScriptableObject() 函数。同样,您可以使用您想要公开的方法传入任何类。但是,对于要公开的方法,您必须使用 [ScriptableMember] 属性对其进行标记。

HtmlPage.RegisterScriptableObject("Page", this);
......
[ScriptableMember]
public void CallMeInSilverlight(string message)
{
    HtmlPage.Window.Alert("The form said: " + message);
}

At this point, your method is exposed to JavaScript on the page and you could call it like so, assuming you added id="silverlightControl"to your <object>element:

此时,您的方法已暴露给页面上的 JavaScript,您可以像这样调用它,假设您添加id="silverlightControl"<object>元素中:

document.getElementById('silverlightControl').Content.Page.CallMeInSilverlight("testing 1 2 3");

Notice the Pageproperty? That's what the call to RegisterScriptableObject()gave us. Now, let's wrap this into a tidy JavaScript method:

留意Page物业吗?这就是电话RegisterScriptableObject()给我们的。现在,让我们把它包装成一个整洁的 JavaScript 方法:

<script type="text/javascript">
    function CallMe(message) {
        var control = document.getElementById('silverlightControl');
        control.Content.Page.CallMeInSilverlight(message);
    }
</script>

And now we can call the CallMe()method from the Windows Forms app like so:

现在我们可以CallMe()从 Windows 窗体应用程序调用该方法,如下所示:

public void CallToSilverlight()
{
    webBrowser.InvokeScript("CallMe", new object[] { "testing 1 2 3" });
}

回答by smaclell

Silverlight in a winform app just sounds like bad news. It would mean you are running to different CLR's in a single app and would have to deal with alot of added complexity to make it work. If possible consider using the full WPF within your app instead here is a linkshowing you how.

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

回答by rudigrobler

Have a look at Desklighter. Not exactly what you are looking for but it does proof that it should be possible?

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

回答by Charles

If all you reallyneed to do is host Silverlight in a desktop app, I'd suggest you check out Jeremiah Morrill's SilverlightViewportproject. It allows you to embed a Silverlight application in a WPF or XNA app. It's still very alpha, but you might find it useful.

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

Here's a picture to wet your appetite:

这是一张让你食欲大开的图片:

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

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