views:

4693

answers:

7

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)

A: 

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 link showing you how.

smaclell
The CoreCLR used by Silverlight supports this scenario of running in process with other CLRs, so this isn't a problem.
Judah Himango
Interesting, thank you for sharing. I was trying to stress that although you can do it, it might not be advisable to do so. Still a neat way to bend the technology to your will.
smaclell
Umm... The CoreCLR will be running on the client. It doesn't run on the server does it?
AnthonyWJones
+1  A: 

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

rudigrobler
+7  A: 

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.

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

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.

[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:

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.

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

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.

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. Unfortunately, I have not yet been able to get the WebBrowser control to actually call the method. Once I figure out a good way to do that, I'll come back and finish this example.

wahrhaft
That's awesome! I hope you can figure out how to get it to work from WebBrowser to WinForm. I haven't seen anyone else on the web do this (or even try...) so it would be great if you can figure it out.
NotDan
A: 

I'm hoping to get the method to directly host a Silverlight control in a WinForm or a VB6/VC6 form without a WebBrowser control. I need to get great UI looking in a traditional windows application via Silverlight, but i wont't use WPF because of it needs dotNetFramework 3.5, which is too large to deploy. And I wont use a WebBrowser control. I think it's possible to use Silverlight in a windows application just like an ActiveX control. But how to do this? The Silverlight.js from microsoft is too difficult to read.

Patrick.Liang
A: 
Charles
A: 

This is more a question than an answer. I tried what wahrhaft said and it worked like a charm.

However I need to debug the Silverlight app while being hosted in the Windows Forms app

How can I do that? I tried running the Host app from windows explorer and then "Attach to Process..." from VS in the Silverlight application, but I had no luck

camilin87
Make sure you set the code type to Silverlight in the attach box. See step 3 from this page: http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx Also, these type of questions should be added as a comment, not an answer.
NotDan
thanks for your reply NotDan, it worked like a charmI didn't add the question as a comment 'cause I couldn't
camilin87
A: 

I'm trying to embed a Silverlight Bing Map into a Windows Forms application using the WebBrowser control. Wahrhaft's approach made it work as long as I run the application from VisualStudio. When I start the application in Windows, Bing Maps won't work because it doesn't work with the file:// protocol. (On the Microsoft page, you can obtain a key for http://localhost, though). I can't use the javascript version of Bing Maps because I need it to zoom nicely with DeepZoom. Does anyone have an idea what I can do to make it work?

Andy