Tuesday, July 01, 2008

Quick Silverlight Tip: How to access HTML DOM from Silverlight and Silverlight managed objects from HTML?

After my session yesterday, I got number of email from people, who have a problem to access HTML DOM from Silverlight and vice verse. I want to answer to all of you by this post.

Access HTML from Silverlight

You have not do anything special in Silverlight to access it.  Your friend is HtmlPage.Window object. For example, if I want to execute window.open JavaScript method from Silverlight, all I have to do is to call:

public void OpenWindow()

        {

HtmlPage.Window.Invoke("open", new object[] { "http://blogs.microsoft.co.il/blogs/tamir", "login", "resizable=1,width=646,height=436" });

        }

HtmlPage.Window.Invoke also returns Object – this is the response of function executed.

Access Silverlight Managed Objects from HTML

Here you should remember two things:

  • You should mark both class and member you want to access with special attributes ScriptableType (for class) and ScriptableMember (for member)
  • Register Scriptable object anywhere (for example in Constructor).

So, if you want OpenWindow method to be exposed from the Page class to HTML, you should use following code:

    [ScriptableType]
public partial class Page : UserControl    {
public Page() {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("Page", this);
        }

[ScriptableMember]
public void OpenWindow() {
object o = HtmlPage.Window.Invoke("open", new object[] { "http://blogs.microsoft.co.il/blogs/tamir", "login", "resizable=1,width=646,height=436" });
        }
}

That’s all, folks. Be good people and have a nice day.

Here the script of test application:

Page.xaml

<UserControl x:Class="DomAccessDemo.Page"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Height="20">

<Grid x:Name="LayoutRoot" Background="White">

<Button Click="Button_Click" Content="Fun!"/>

</Grid>

</UserControl>

Page.xaml.cs

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Browser;

using System.ComponentModel;

namespace DomAccessDemo

{

    [ScriptableType]

public partial class Page : UserControl

    {

public Page()

        {

            InitializeComponent();

HtmlPage.RegisterScriptableObject("Page", this);

        }

private void Button_Click(object sender, RoutedEventArgs e)

        {

            OpenWindow();

        }

        [ScriptableMember]

public void OpenWindow()

        {

object o = HtmlPage.Window.Invoke("open", new object[] { "http://blogs.microsoft.co.il/blogs/tamir", "login", "resizable=1,width=646,height=436" });

        }

    }

}

DomAccessDemoTestPage.aspx

<html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">

<head runat="server">

<title>Test Page For DomAccessDemo</title>

<script language="javascript">

function testSL()

        {

var xaml = document.getElementById("Xaml1");

            xaml.Content.Page.OpenWindow();

        }

</script>

</head>

<body style="height:100%;margin:0;">

<form id="form1" runat="server" style="height:100%;">

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

<div style="height:100%;">

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/DomAccessDemo.xap" MinimumVersion="2.0.30523" Width="100%" Height="100%" />

</div>

</form>

<button onmouseup="testSL();">Test</button>

</body>

</html>

No comments: