Saturday, March 28, 2009

Html Host control in Silverlight

The revised and latest version of this control can be found at revised silverlight htmlhost.

It is generally a problem in silverlight to use the HTML content. First and foremost problem is the trouble with setting the position of the control based on the silverlight page we are creating. Also it is really clunky to write the code to read and write your div details by accessing the HTML DOM objects.

Ofcourse Silverlight exposes these HTML DOM objects in the System.Windows.Browser namespace by the classes like HTMLDocument, HTMLElement, HTMLPage etc., These classes provide functions like CreateElement, which can create the controls we want. I've used this function to create the IFRAME which I finally position properly on the page using some properties exposed.

This is a clean way of using the HTML IFrame in your code. Feel free to use the source and add more functionality. If you think your new functionality may be useful to someone else, pls let me know by dropping an email to muthu.v (@) g mail dot com.

How the Html Host control was built:

This creates a DIV inside the HTMLPage.Document.Body and adds an IFRAME object to the DIV control. This uses the classes like HtmlDocument, HtmlElement, HtmlPage for creating these and adds them to the HTML Document object. This has been tested to work fine in IE8 and FireFox. If any of you find any issues and fixes, pls let me know I'll fix and upload again. That will be useful to our programming community.

I've not added much of design time support. So after adding the control, you need to call a function InitControl() for this to be rendered. Also positioning of the control can be done by using the properties HtmlControlTop and HtmlControlLeft properties. Width and Height are exposed as "Width" and "Height" only.
How to use the Html Host control:
  1. Create a new Silverlight application or add a new Silverlight User Control (page) into your existing application.
  2. Reference the FreeHtmlHost.dll in the project.
  3. Add the namespace reference to the silverlight user control on the top like this.

    xmlns:cust="clr-namespace:FreeHtmlHost;assembly=FreeHtmlHost"

  4. Add the control in the location you want like this. Adjust the position of the controls according to your needs.

    <cust:FreeHtmlHost x:Name="customHost" Width="620" HtmlControlTop="50" HtmlControlLeft="30" Height="500" NavigationUrl="http://www.microsoft.com"/>


  5. Call the customHost.InitControl(); function in the Page load event of the control or the constructor of your Page.xaml.cs file after the 'InitializeComponent()' function.
The isWindowless property determines whether the HTML is displayed on top of silverlight. If set to true, the HTML controls behind the silverlight plugin are displayed and if false, the silverlight is displayed on top of HTML. This must be set to true while using this HTML host control.

There is another option of background=transparent which makes the background of the plugin to invisible. This option should be avoided as this might hit the performance of the app. We need not worry about this property for using this control. Leave it to its default.

There is another property enableHTMLAccess property which provides a layer of security to specify whether the silverlight code should access HTML DOM or not. This is by default set to true even if you don't use it.

Download Source:

You can download the Visual Studio 2008 control source file at FreeHtmlHost source.

The sample code using this library can be found at Sample Project.

19 comments:

Dewey said...

If you left click on the control, then click on the Silverlight area, the control disappers.

Probably something to do with transparency.

muthu.v said...

Hmm, strange. I could not replicate it. The control is hosted on the SilverlightControl1.xaml file. Did you use that one or the other page? I'll upload the updated project just with one single page.

Dewey said...

Interesting, I tried your new version, and I get the same behavior, with one difference.

The control now comes back after a few seconds, like it's on a timer of some sort.

By the way, I changed nothing in your project originally, I just compiled and ran it.

I really hope we can resolve this, because this is a MUCH needed addition to the SL community.

Dewey said...

Ok, I found out what's going on, but I'm not sure of the solution.

If you use the page HtmlHostAppTestPage.html, you get the bad behavior. However, if you use the page HtmlHostAppTestPage.aspx, it works perfectly.

I thought they were supposed to yield the exact same results.

muthu.v said...

You are right. We need to find why this happens in html pages. It disappears if I click outside and reappears when I use the scroll wheel in the mouse.

muthu.v said...

Fixed the issues. The problem was because I have not set the windowless property to true in the html file. Hope this becomes helpful to people now.

Dewey said...

That's it, unfortunately you pay a very large performance penalty when this is the case.

I knew there was something about overlaying HTML on Silverlight.

kura said...

Hi,
This Htmlhost is very nice.

But I need to place this control in a drag dock panel. My controls are in this higherarchy.
Dragdockpanelhost-->
Dragdockpanel-->
Stackpanel as content of dragdockpanel.
Now, I have added this htmlhost as child to stackpanel.

This htmlhost control is not embeded into the stackpanel though i add it as child of it.

Can you plz help me how to do this??

Tin said...

I have javascript inside the page that is in the iframe. How can I invoke the javascript inside that iframe?

ScriptObject myfunc= (ScriptObject)iframe.GetProperty("myfunc");

it doesn't work.

Giving the iframe's src = javascript: myfunc(); also doesn't work.

Tin said...

well, I found some article that help me with my work. If any of you having the same problem , take a look at http://www.webmasterworld.com/forum91/4384.htm

pansa said...

i need to close FreeHtmlHost control when i click button.

Bill said...

This is awesome, thank you. I'm currently trying to use this in a navigation application (RIA Services Business Application). Any idea how to destroy this control once I navigate to another view? I tried the following to no avail. Thanks!

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);

customHost.Visibility = System.Windows.Visibility.Collapsed;
}

jorge said...

hi this control is awesome, thanks!!
but, when i change to fullscreen mode the control disappear...
can somebody tell me why happens?
thanks for your help

Dan said...

Awesome control! But I am having the same problem as Bill, using this in a RIA services LOB app and need to destroy it once you move to another view. Any ideas?

Dan said...

Ok figured out how to remove the control from the view. I added another property called ID to the FreeHtmlHost code and instead of using a GUID to set the ID of the divIFrameHost I used what was passed in. So in the silverlight app I set the ID property when I set the other property's.

Next I created a new method in the FreeHtmlHost called DestroyControl
public void DestroyControl()
{
HtmlDocument doc = HtmlPage.Document;
divIFrameHost = doc.GetElementById(ID);

doc.Body.RemoveChild(divIFrameHost);
}
I then called the DestroyControl method from the OnNavigatingFrom event handler in the silverlight view.
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
customHost.DestroyControl();
}
Everything is gone when you switch views.

Don said...

This control works well for me, thanks.
Can someone please let me know how to load the NavigationUrl="http://www.microsoft.com" in the page load event in SilverlightControl1.xaml.cs file. The NavigationUrl="http://www.microsoft.com" is now hard coded on the xaml page and I would like to dynamically load different URL in difference cases when the page is loaded.

Many thanks

Jerry said...

I used your control, and got a problem when I try to host asp page with javascript function. The javascript function has the following code:
....
if(parent.location.href != self.location.href){
parent.location.href = self.location.href;
}
...

the error "permission denied" will occur when the application runs to "parent.location.href".
Is this something related with cross domain? the asp page is not in the same domain as the siliverlight control.

Is there any setting in the hosted page website to allow this?

Jerry said...

I used your control, and got a problem when I try to host asp page with javascript function. The javascript function has the following code:
....
if(parent.location.href != self.location.href){
parent.location.href = self.location.href;
}
...

the error "permission denied" will occur when the application runs to "parent.location.href".
Is this something related with cross domain? the asp page is not in the same domain as the siliverlight control.

Is there any setting in the hosted page website to allow this?

Pawan said...

I am not able to download the code. Please help me.