Taoffi's blog

prisonniers du temps

Html Content Viewer for Silverlight

In a previous post, I talked about a solution to manipulate (animate for example) the Silverlight control inside the hosting html page.

 

The reverse side of the problem (displaying html content inside a Silverlight control), is a requirement which comes out in the context of numerous web projects.

 

Some of the proposed solutions suggest html translators in order to obtain the final text into a sort of ‘Rich Edit’ control.

Although it is very good to have a rich edit Silverlight control, the solution seems too tedious to solve a relatively simple problem: displaying html content into an html page (i.e. the page hosting our Silverlight control).

 

Building on the previous sample of animating the Silverlight control into the hosting page, I tried to make a user control that dynamically creates an iFrame to display the desired html content inside the main Silverlight page.

 

You can have a look at the proof of concept Here!

 

 

 

Dynamically create an html control

Suppose we want to display the html page: http://mycompany.com/page.html inside our Silverlight control.

 

The solution can be:

§  Use the HtmlPage to locate the hosting HtmlElement (where our Silverlight control lives: that can be straightforward:  HtmlPage.Plugin.Parent;)

§  Create a new html container (for example, a DIV)

§  Place an iframe html element inside this container

§  Set the iframe source to the desired page

§  Insert the container into the hosting HtmlElement

 

 

Here is a sample code illustrating these steps

 

private void CreateHtmlContent()

{

       HtmlElement  plugin_div   = HtmlPage.Plugin.Parent,

                    new_div      = HtmlPage.Document.CreateElement("div"),

                    iframe       = HtmlPage.Document.CreateElement("iframe");

 

       /// set the new div position to absolute

       new_div.SetStyleAttribute("position", "absolute");

       new_div.SetStyleAttribute("z-order", "5");

 

       new_div.SetStyleAttribute("left", "200px");

       new_div.SetStyleAttribute("top", "40px");

       new_div.SetStyleAttribute("width", "400px");

       new_div.SetStyleAttribute("height", "400px");

 

       /// setup the iframe style, attributes and target page

       iframe.SetStyleAttribute("width", "100%");

       iframe.SetStyleAttribute("height", "100%");

       iframe.SetAttribute("src", "http://www.isosoft.org/taoffi/");

 

       /// add the iframe to the new div

       new_div.AppendChild(iframe);

 

       /// add the new div to the hosting html page

       plugin_div.AppendChild(new_div);

}

 

The solution exposed here can be a suitable foundation to solve many situations where html content can be composed and/or displayed inline within a Silverlight control.

Let us begin by making a custom control, a HtmlContentViewer say!

 

The sample code exposes some more!

 

SilverHtmlContent.zip (49.34 kb)

Scrollable ComboBox

I am working on a new Silverlight user interface version of Simplesite.net and, as anyone can imagine, that involves a good dive into Silverlight as a ‘Line Of Business’ application technology.

One of the problems I encountered was to make the Combo box control able to respond to Mouse Wheel messages.

After having searched on different blogs and web sites, I didn’t find a suitable solution and ended up by delving into the subject.

Some of the proposed solutions consisted in ‘bringing into view’ one of the combo box items to force the list to scroll up or down as required… that seemed a little bit like a good workaround but was not very efficient and had a bad visual aspect.

 

What is a Silverlight ComboBox?

One of the nice (and pedagogic) aspects in Expression Blend is to be able to edit any existent control template (right click the control, select Edit Template / Edit a copy).

 

 

In Expression Blend, a Control Template reveals all the components of the control… this helps to understand some of the internal mechanisms of the control and how to use them efficiently.

 

To know more about the ComboBox control, I used Blend to insert one somewhere, and selected to edit a copy of its template.

That revealed the main components of the control:

§ A Layout Grid, containing:

§ A border (content presenter border) containing the static part of the combobox;

§ A Popup containing a ScrollViewer which will display the items.

 

It now seems clear that the scroll problem should be handled at the ScrollViewer component.

 

The SetIsMouseWheelScrollingEnabled method of the ScrollViewer can simply be used to activate the Mouse Wheel message handling for this component.

 

The solution

I saved my template to the application resources (App.xaml) with x:key=”combo_box_template”

<!-- ************* scrollable combo box template *******************************-->

<ControlTemplate x:Key="combo_box_template" TargetType="ComboBox">

 

 

I then created a class named ScrollableComboBox deriving from ComboBox

The control template is loaded and applied at class’s instantiation… and Mouse Wheel handling activated on the corresponding ScrollViewer component.

 

 

public partial class ScrollableComboBox : ComboBox

{

       protected ScrollViewer            m_scroll_viewer            = null;

 

       public ScrollableComboBox()

       {

             this.Style   = (Style) App.Current.Resources["ScrollableComboBoxStyle"];

             this.Template = (ControlTemplate) App.Current.Resources["combo_box_template"];

             this.ApplyTemplate();

            

             m_scroll_viewer = (ScrollViewer)GetTemplateChild("ScrollViewer");

 

             if (m_scroll_viewer != null)

             {

                    m_scroll_viewer.SetIsMouseWheelScrollingEnabled(true);

             }

    }

 

 

Surprisingly, that is all we need to activate scrolling on a Silverlight ComboBox!

We can now insert a ScrollableComboBox anywhere we need.