Microsoft Most Valuable Professional

Chris Pietschmann

An MVP From Wisconsin

Silverlight and JavaScript Interop Basics

I've been looking into Silverlight in my spare time a bit, to see what it has to offer, and the JavaScript "Interop" is actually pretty neat and simple to use. About three months ago I wrote a post titled "Working with HTML DOM in Silverlight using the Bridge Pattern"; so I think this time I'll go over some of the basics involved with communicating back and forth between Silverlight and JavaScript. This article is written by referencing Silverlight 2 Beta 2, but should still hold relevent in the final release of Silverlight 2.

Call a JavaScript Methods from within Silverlight

1) Using the Eval method

Silverlight does expose the JavaScript Eval method, so you can use it to call some JavaScript in the page

Here's a couple examples of calling Eval from in Silverlight:

using System.Windows.Browser;

// set a global variable
HtmlPage.Window.Eval("myJSObject = 2;");

// invoke a global method
HtmlPage.Window.Eval("myJSMethod();");

One thing to keep in mind with using Eval, even from Silverlight, is you can potentially open yourself up to script injection vulnerabilities. Instead of using Eval, you should use Invoke, which is my next example.

2) Using the Invoke method

You can use the Invoke method to execute some global JavaScript method within your page.

Here's a couple examples, one without arguments, the other passing in two arguments:

using System.Windows.Browser;

// Call a global method without passing in arguments
HtmlPage.Window.Invoke("myJSMethod");

// Call a global method, pass in two arguments
// First argument is a string
// Second argument is an integer
HtmlPage.Window.Invoke("myJSMethod", "Chris", 42);

Returning Values From JavaScript Method Calls

Now that we've covered how to execute JavaScript methods from Silverlight, I'll show how to captures values that are returned from those method call.

Both the Eval and Invoke methods return an Object. The Object returned is a reference to the JavaScript object that is returned from the method call. To get at the returned value the Object needs to be cast into the appropriate data type.

Here's some examples of casting the ScriptObject to different data types to return different data types from JavaScript methods:

// Returning a Double
double doubleValue = (double)HtmlPage.Window.Invoke("myJSMethod");

// Returning a String
string stringValue = (string)HtmlPage.Window.Invoke("myJSMethod");

One thing to always rememer when casting the object returned to a specific data type, is to check for NULL before casting, just to make sure a value was returned.

Returning Objects From JavaScript Method Calls and Accessing Its Methods and Properties

You can also pass back Objects to Silverlight from your JavaScript methods calls. Instead of casting the object returned from the Eval or Invoke method call to a double, string or any other data type; you'll need to cast it to a ScriptObject. ScriptObject is basically the data type used for a "general" JavaScript object.

// Execute the global JavaScript method and cast it to ScriptObject
ScriptObject myScriptObject = (ScriptObject)HtmlPage.Window.Invoke("myJSMethod");

1) Accessing the ScriptObjects Properties

You can access the properties of the ScriptObject using the GetProperty method, then you must cast it to the appropriate data type.

// Get a Double Property value from our ScriptObject
double doubleValue = (double)myScriptObject.GetProperty("DoubleValue");

// Get a String Property value from our ScriptObject
double stringValue = (string)myScriptObject.GetProperty("StringValue");

2) Invoke one of the ScriptObjects Methods

The ScriptObject has an Invoke method that works just like the HtmlPage.Window.Invoke method shown above.

// Invoke a method that doesn't return a value
myScriptObject.Invoke("myMethod");

// Invoke a method that returns a string value, and pass in some arguments
string stringValue = myScriptObject.Invoke("myMethod", "Chris", 42);

Here's the JavaScript code that defines an object that has the properties and method show above:

var myJSObject = function(){
    this.DoubleValue = 42;
    this.StringValue = "Chris";
};
myJSObject.prototype.myMethod = function(arg1, arg2){
    return "Chris";
};

Call Silverlight Methods From JavaScript

You can also call Silverlight methods from within JavaScript and return values from them.

1) Setup your Silverlight object as Scriptable

In order to interact with a Silverlight object from within JavaScript, it must be marked with the ScriptableType attribute, and any methods you want to expose need to be marked with the ScriptableMember attribute. Also, you must register the object as Scriptable in the page once the page loads, and give the object an alias that will be used to reference it within JavaScript.

Here's a sample of a page that exposes a method to be called from JavaScript:

[ScriptableType]
public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
        this.Loaded += new System.Windows.RoutedEventHandler(Page_Loaded);
    }

    void Page_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        // Register this object in the page as Scriptable
        // so it can be access from within JavaScript
        HtmlPage.RegisterScriptableObject("myObject", this);
    }

    [ScriptableMember]
    public double GetDoubleValue()
    {
        // return a double
        return (double)42;
    }
}

2) Write your JavaScript code

When writing your JavaScript code, you need to get a reference to the Silverlight Plugin in the page, so you can call methods on your Silverlight object.

Here's a small example of doing this with a JavaScript method that calls the Silverlight method wired up to be fired on click of a button. In this example I'm using ASP.NET and the ASP.NET Silveright control.

<code:html>

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">
<head runat="server">
    <title>Test Page For SilverlightJavaScriptInteropArticleCode</title>
    <script type="text/javascript">
        function callGetDoubleValue()
        {
            // Get a reference to the Silverlight Plugin
            // Since we're using the ASP.NET Silverlight control
            // we can use $find with the controls ClientID to get
            // a reference to it
            var pluginObject = $find("<%=Xaml1.ClientID%>");
            // Get a reference to the actual Silverlight
            // plugin element within the page
            var plugin = pluginObject.get_element();
           
            // Call the GetDoubleValue method of our Silverlight object
            // notice we are referencing the object by the name of "myObject", that we setup
            // in Silverlight when we registered the object as Scriptable
            var dbl = plugin.Content.myObject.GetDoubleValue();

            // Display the value to the user in an alert box
            alert(dbl);
        }
    </script>
</head>
<body style="height:100%;margin:0;">
    <form id="form1" runat="server" style="height:100%;">

        <!-- The button that calls the js method above -->
        <input type="button" value="test" onclick="callGetDoubleValue();" />

        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <div  style="height:100%;">
            <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightJavaScriptInteropArticleCode.xap" MinimumVersion="2.0.30523" Width="100%" Height="100%" />
        </div>
    </form>
</body>
</html>

</code>

Return Objects From Silverlight Method Calls To JavaScript

You can also return more complex object references to JavaScript from Silverlight method calls. One thing to remember, when returning objects from a Silverlight method call to JavaScript, is they need to be marked as Scriptble using the ScriptableType attribute, and the member (properties and methods) you want to expose must be marked with the ScriptableMember attribute.

Here's an example method to be called by JavaScript that returns an object type that is marked as Scriptable:

[ScriptableMember]
public myObject GetObjectValue()
{
    myObject o = new myObject();
    o.Name = "Chris";
    return o;
}

[ScriptableType]
public class myObject
{
    [ScriptableMember]
    public string Name { get; set; }

    [ScriptableMember]
    public string GetName()
    {
        return this.Name;
    }
}

Here's the simple JavaScript (based on the other example above) to call the method and access the returned objects properties and methods:

// Call the method and get the returned object
var obj = plugin.Content.myObject.GetObjectValue();

// Get the value of a property of the retured object
var strName = obj.Name;

// Get the returned value of a method of the returned object
var strName = obj.GetName();

Conclusion

The JavaScript interop in Silverlight is fairly simple to use, however the ability to call Silverlight from JavaScript was a little tricky for me at first, mostly due to how few Silverlight articles are out there. I hope this helps you get your JavaScript code (new or existing) working along-side Silverlight in a friendly fashion.

Also, here's a couple related posts I've written during the last couple months. The were written with Silverlight 2 Beta 1 as reference, but they still hold relevent with Beta 2.

Working with HTML DOM in Silverlight 2 Beta 1 using the Bridge Pattern

Show a MessageBox in Silverlight 2 Beta 1

Silverlight: Load JavaScript from Embedded Resource and Execute Within Page

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Thursday, June 19, 2008 11:18 PM
Permalink | Comments (7) | Post RSSRSS comment feed


Silverlight: Load JavaScript from Embedded Resource and Execute Within Page

I've been playing around with Silverlight 2 Beta 1 alot lately, and one of the areas I've been focusing on is interoperability with JavaScript and the DOM. Here's a technique I've found that allows you to inject JavaScript into the page from within your Silverlight application. This example also starts with the idea that the JavaScript you are going to inject is stored as an Embedded Resource within your Silverlight Application.

Step 1: Create your JavaScript (.js) file and add it as an embedded resource to your Silverlight Application.

Step 2: Place code in your app that loads the embedded JavaScript file to a string variable:

// Load JavaScript code from Embedded Resource
System.IO.Stream stream = this.GetType().Assembly.GetManifestResourceStream("[namespace].[javascriptFileName]");
System.IO.StreamReader reader = new System.IO.StreamReader(stream);
string script = reader.ReadToEnd();

Note: Replace the [namespace] text above with the full namespace of your Silverlight application project. Also, replace the [javascriptFileName] text above with the filename of your JavaScript file. An example value for this with the namespace and JavaScript filename is "MyApplication.TestScript.js".

Step 3: Inject the JavaScript into the page using Eval:

HtmlPage.Window.Eval(script);

This is a small technique that I've found to make mixing JavaScript with Silverlight a little easier since this allows you to take advantage of JavaScript Intellisense within Visual Studio 2008; where if you just placed the JavaScript code inline within your C# or VB.NET code you would not be able to have JavaScript Intellisense.

Currently rated 3.7 by 3 people

  • Currently 3.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Monday, May 19, 2008 8:32 PM
Permalink | Comments (0) | Post RSSRSS comment feed


Mono: WinForms finally API complete and Moonlight v1.0 is released

It's been forever since I posted anything about Mono, but this stuff deserves some attention.

Mono's Winforms 2.0 is now API Complete

Yesterday, it was announced that the System.Windows.Forms support in Mono (an open source implementation of the .NET Framework targeting Linux, MacOS, Windows, etc.) has finally reached a state of being API complete. This means the public API for WinForms in Mono is exactly the same as in .NET; with a total of 12,776 methods! The first check-in of WinForms occurred on July 8th, 2004; which means it took almost 4 years to implement.
Original Source: http://tirania.org/blog/archive/2008/May-13.html

First Moonlight Release

On May 13, the Mono guys released the first public release of Moonlight, supporting the Silverlight 1.0 profile for Linux. If you don't know what Moonlight is; Moonlight is an open source implementation of Microsoft's Silverlight for Linux.
Original Source: http://tirania.org/blog/archive/2008/May-13-1.html

I'm excited to see that Mono is making some awesome progress in bringing the greatness that is the .NET Framework to Unix, Linux, MacOS, and other operating systems that are non-Microsoft. Way to go guys!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by crpietschmann on Wednesday, May 14, 2008 4:36 PM
Permalink | Comments (0) | Post RSSRSS comment feed


PasswordTextBox for Silverlight 2 Beta 2

The standard TextBox control that is built into Silverlight 2 Beta 2 is a bit lacking and is missing alot of features that we have become accustomed to in a TextBox. One of those features is being able to mask the characters being displayed when its used to accept passwords. Here's a small PasswordTextBox control I built that does just that; it masks the characters from being displayed so you can accept passwords like you're used to.

Update 6/7/2008 - I just tested this with Silverlight 2 Beta 2 and it works just the same as it does with Beta 1. 

Updated 3/17/2008 - I updated this code to support the Delete and Backspace keys, and to maintain caret/cursor position within the box. I also added the PasswordChar property that defines what the masking character is used to hide the password entered.

/// Copyright 2008 Chris Pietschmann (http://pietschsoft.com)
/// This work is licensed under a Creative Commons Attribution 3.0 United States License
/// http://creativecommons.org/licenses/by/3.0/us/
///
/// This is a Password TextBox built for use with Silverlight 2 Beta 1
/// The reason this was built, is because the standard TextBox in
/// Silverlight 2 Beta 1 does not have Password support.
/// Original Link: http://pietschsoft.com/post/2008/03/PasswordTextBox-for-Silverlight-2-Beta-1.aspx
///

using System.Windows.Controls;

namespace SilverlightPasswordTextBox
{
    public partial class PasswordTextBox : TextBox
    {
        public PasswordTextBox()
        {
            this.TextChanged += new TextChangedEventHandler(PasswordTextBox_TextChanged);
            this.KeyDown += new System.Windows.Input.KeyEventHandler(PasswordTextBox_KeyDown);
        }

        #region Event Handlers

        public void PasswordTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (base.Text.Length >= _Text.Length)
                _Text += base.Text.Substring(_Text.Length);
            DisplayMaskedCharacters();
        }

        public void PasswordTextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            int cursorPosition = this.SelectionStart;
            int selectionLength = this.SelectionLength;

            // Handle Delete and Backspace Keys Appropriately
            if (e.Key == System.Windows.Input.Key.Back
                || e.Key == System.Windows.Input.Key.Delete)
            {
                if (cursorPosition < _Text.Length)
                    _Text = _Text.Remove(cursorPosition, (selectionLength > 0 ? selectionLength : 1));
            }
           
            base.Text = _Text;
            this.Select((cursorPosition > _Text.Length ? _Text.Length : cursorPosition), 0);
            DisplayMaskedCharacters();
        }

        #endregion

        #region Private Methods

        private void DisplayMaskedCharacters()
        {
            int cursorPosition = this.SelectionStart;
           
            // This changes the Text property of the base TextBox class to display all Asterisks in the control
            base.Text = new string(_PasswordChar, _Text.Length);

            this.Select((cursorPosition > _Text.Length ? _Text.Length : cursorPosition), 0);
        }

        #endregion

        #region Properties

        private string _Text = string.Empty;
        /// <summary>
        /// The text associated with the control.
        /// </summary>
        public new string Text
        {
            get { return _Text; }
            set
            {
                _Text = value;
                DisplayMaskedCharacters();
            }
        }

        private char _PasswordChar = '*';
        /// <summary>
        /// Indicates the character to display for password input.
        /// </summary>
        public char PasswordChar
        {
            get { return _PasswordChar; }
            set { _PasswordChar = value; }
        }

        #endregion
    }
}

Update 4/2/2008: Here's the above code translated to VB.NET

'' Copyright 2008 Chris Pietschmann (http://pietschsoft.com)
'' This work is licensed under a Creative Commons Attribution 3.0 United States License
'' http://creativecommons.org/licenses/by/3.0/us/
''
'' This is a Password TextBox built for use with Silverlight 2 Beta 1
'' The reason this was built, is because the standard TextBox in
'' Silverlight 2 Beta 1 does not have Password support.
'' Original Link: http://pietschsoft.com/post/2008/03/PasswordTextBox-for-Silverlight-2-Beta-1.aspx
Public Class PasswordTextBox
    Inherits TextBox

    Public Sub PasswordTextBox_TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs) Handles Me.TextChanged
        If MyBase.Text.Length >= _Text.Length Then
            _Text += MyBase.Text.Substring(_Text.Length)
        End If
        DisplayMaskedCharacters()
    End Sub

    Public Sub PasswordTextBox_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles Me.KeyDown
        Dim cursorPosition As Integer = Me.SelectionStart
        Dim selectionLength As Integer = Me.SelectionLength

        '' Handle Delete and Backspace Keys Appropriately
        If e.Key = Key.Back Or e.Key = Key.Delete Then
            If cursorPosition < _Text.Length Then
                Dim lengthToRemove As Integer = 1
                If selectionLength > 0 Then lengthToRemove = selectionLength
                _Text = _Text.Remove(cursorPosition, lengthToRemove)
            End If
        End If

        MyBase.Text = _Text
        If cursorPosition > _Text.Length Then
            Me.Select(_Text.Length, 0)
        Else
            Me.Select(cursorPosition, 0)
        End If
        DisplayMaskedCharacters()
    End Sub

    Private Sub DisplayMaskedCharacters()
        Dim cursorPosition As Integer = Me.SelectionStart

        '' This changes the Text property of the base TextBox class to display all Asterisks in the control
        MyBase.Text = New String(_PasswordChar, _Text.Length)

        If cursorPosition > _Text.Length Then
            Me.Select(_Text.Length, 0)
        Else
            Me.Select(cursorPosition, 0)
        End If
    End Sub

    Private _Text As String = String.Empty
    Overloads Property Text() As String
        Get
            Return _Text
        End Get
        Set(ByVal value As String)
            _Text = value
            DisplayMaskedCharacters()
        End Set
    End Property

    Private _PasswordChar As Char = "*"
    Public Property PasswordChar() As Char
        Get
            Return _PasswordChar
        End Get
        Set(ByVal value As Char)
            _PasswordChar = value
        End Set
    End Property

End Class

 

Currently rated 3.8 by 16 people

  • Currently 3.75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Friday, March 14, 2008 8:25 PM
Permalink | Comments (13) | Post RSSRSS comment feed

Working with HTML DOM in Silverlight 2 Beta 1 using the Bridge Pattern

Working with the HTML DOM in Silverlight 2 Beta 1 is rather simple and easy to do. However, to my surprise it's a similar experience to working the the HTML DOM from within JavaScript; you have to know the name of the properties to get/set and you don't have the luxury of compile time checking or intellisense.

Here an example of creating a new DIV element and setting some of it's properties:

HtmlElement myDiv = HtmlPage.Document.CreateElement("div");

// Set the innerHTML property
myDiv.SetProperty("innerHTML", "<strong>Some HTML Content</strong>");

// Set some style properties
myDiv.SetStyleAttribute("border", "solid 1px black");
myDiv.SetStyleAttribute("position", "absolute");
myDiv.SetStyleAttribute("top", "10px");
myDiv.SetStyleAttribute("left", "10px");

// Add the myDiv element to the page
HtmlPage.Document.Body.AppendChild(myDiv);

// Get the innerHTML property
string html = myDiv.GetProperty("innerHTML");

// Get the Position Style attribute
string pos = myDiv.GetStyleAttribute("position");

As you can see from the above example, the HtmlElement object doesn't have any real properties or style attributes, you must work with the helper methods to get/set them. I was a little surprised to see this at first, and I don't know if they plan on adding any properties to the object in the final release or if they are doing this to just make the Silverlight download smaller.

Can We Extend the HtmlElement to Add Property Accessors?

Yes, but not through inheritence. For some reason they decided to make the System.Windows.Browser.HtmlElement class Sealed! So, instead we'll have to use the Bridge Pattern to create a wrapper object that will have all the desired property accessors.

Here's an example of using a class that implements the Bridge Pattern to do the exact same as above:

HtmlElementHelper myDiv = new HtmlElementHelper(HtmlPage.Document.CreateElement("div"));
myDiv.innerHTML = "<strong>Some HTML Content</strong>";
myDiv.Style.Position = "absolute";
myDiv.Style.Border = "solid 1px black";
myDiv.Style.Top = "10px";
myDiv.Style.Left = "10px";
HtmlPage.Document.Body.AppendChild(myDiv.Element);

Not only is the code using the Bridge Pattern easier to read, but now we have the benefit of compile time checking of our DIV elements properties. No need to worry if you misspelled any of the property names anymore.

Full Source Code for the HtmlElementHelper Bridge class:

 public class HtmlElementHelper
    {
        private HtmlElement _elem = null;
        private HtmlElementStyleHelper _styleHelper = null;
       
        public HtmlElementHelper(HtmlElement elem)
        {
            this._elem = elem;
        }

        public HtmlElement Element
        {
            get { return _elem; }
        }

        public object GetProperty(string propertyName)
        {
            return _elem.GetProperty(propertyName);
        }

        public void SetProperty(string propertyName, object value)
        {
            _elem.SetProperty(propertyName, value);
        }
       
        public HtmlElementStyleHelper Style
        {
            get
            {
                if (_styleHelper == null)
                {
                    _styleHelper = new HtmlElementStyleHelper(this._elem);
                }
                return _styleHelper;
            }
        }

        public string innerHTML
        {
            get { return GetProperty("innerHTML") as string; }
            set { this.SetProperty("innerHTML", value); }
        }

        public string innerText
        {
            get { return GetProperty("innerText") as string; }
            set { this.SetProperty("innerText", value); }
        }

        public string className
        {
            get { return GetProperty("className") as string; }
            set { SetProperty("className", value); }
        }

        public string Id
        {
            get { return _elem.Id; }
            set { _elem.Id = value; }
        }
    }

    public class HtmlElementStyleHelper
    {
        private HtmlElement _elem = null;

        public HtmlElementStyleHelper(HtmlElement elem)
        {
            this._elem = elem;
        }

        public string GetAttribute(string name)
        {
            return _elem.GetStyleAttribute(name);
        }

        public void SetAttribute(string name, string value)
        {
            _elem.SetStyleAttribute(name, value);
        }

        public string Position
        {
            get { return GetAttribute("position"); }
            set { SetAttribute("position", value); }
        }

        public string Border
        {
            get { return GetAttribute("border"); }
            set { SetAttribute("border", value); }
        }

        public string Top
        {
            get { return GetAttribute("top"); }
            set { SetAttribute("top", value); }
        }

        public string Left
        {
            get { return GetAttribute("left"); }
            set { SetAttribute("left", value); }
        }

        public string Width
        {
            get { return GetAttribute("width"); }
            set { SetAttribute("width", value); }
        }

        public string Height
        {
            get { return GetAttribute("height"); }
            set { SetAttribute("height", value); }
        }
    }

Conclusion

I have actually never had such a usefull need to use the Bridge Pattern before, and this time it really saves the day. I hope Microsoft adds better support for the different HTML DOM Elements properties and style properties to the Silverlight 2 final release, or at least open up the HtmlElement object for inheritence. If neither, at least we can use the Bridge Pattern to fullfill our needs.

Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Wednesday, March 12, 2008 12:00 AM
Permalink | Comments (3) | Post RSSRSS comment feed

Show a MessageBox in Silverlight 2 Beta 1

Since Silverlight is just a subset of WPF, there are alot of things missing. One missing thing I found is the System.Windows.MessageBox. I'm a little puzzled as to why they would have left this out, but I imagine MessageBox's are handled very differently in different Operating Systems. It's probably a little work to get it working on both Mac and Windows, but I hope it gets into the final release. It's not a major feature, but one that is used quite often when developing desktop applications, so I can see it being used alot in Silverlight applications.

Anyways, here's a small implementation I wrote that wraps up the JavaScript Alert to give us a basic MessageBox to use for now:

public static class MessageBox
{
    public static void Show(string message)
    {
        HtmlPage.Window.Alert(message);
    }
}

Update 4/2/2008: I updated the above example to use the "HtmlPage.Window.Alert" method instead of the Invoke method; better to use the method that's already in the framework.

Also, here's the above code example in VB.NET:

Module MessageBox
    Public Sub Show(ByVal message As String)
        HtmlPage.Window.Alert(message)
    End Sub
End Module

 

Currently rated 5.0 by 6 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Saturday, March 08, 2008 6:13 PM
Permalink | Comments (2) | Post RSSRSS comment feed

Opening Client-Side Files using Silverlight

Silverlight does not have direct access to the local file system for security reasons. However, you can still prompt the user to select a specific file to open using the OpenFileDialog similarly to how you do in .NET. Here's some basic code that demonstrates opening a user specified file using Silverlight 2 Beta 1.

This basic example opens up a user specified file, and displays its contents within a textbox.

Page.xaml file

<UserControl x:Class="SilverlightFileSystemInfo.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="480">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid HorizontalAlignment="Left">
            <TextBox x:Name="txtFile" Width="400" Height="250" AcceptsReturn="True" />   
        </Grid>
        <Grid HorizontalAlignment="Right" VerticalAlignment="Top">
            <Button x:Name="btnSelectFile" Content="Add File" Width="75" Height="30" Click="btnSelectFile_Click"></Button>
        </Grid>
    </Grid>
</UserControl>

Page.xaml.cs file 

using System.Windows;
using System.Windows.Controls;
using System.IO;

namespace SilverlightOpenFileTest
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }

        private void btnSelectFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();

            // Show the Open File Dialog
            DialogResult result = fileDialog.ShowDialog();

            // Open the file if OK was clicked in the dialog
            if (result == DialogResult.OK)
            {
                FileDialogFileInfo fi = fileDialog.SelectedFile;
                Stream s = fi.OpenRead();
                StreamReader reader = new StreamReader(s);
                txtFile.Text = reader.ReadToEnd();
            }
        }
    }
}

Now isn't that simple? I wonder if they'll ever add the SaveFileDialog...

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Wednesday, March 05, 2008 11:09 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Silverlight: Anatomy of an .XAP file

Silverlight 2 Beta 1 just came out this morning, so I started checking it out immediately. I installed the Silverlight Tools for Visual Studio and noticed that when a Silverlight Application is compiled a .xap file is created that contains the application. But, what exactly is a .xap file, and what exaclty is in there?

What is an .xap file?

A .xap file is basically a compiled Silverlight application. The file is actually a .zip file that contains all the files necessary for the application. Just rename the .xap file to have a .zip extension and then you can open it up to see its contents. Just try it yourself.

What files are contained within the .xap file?

The .xap file contains an application manifest (AppManifest.xaml) file and all the necessary DLL's that are required by the application. The first DLL contained is the compiled version of you application and has the same name of your application. In my test I created an application names "SilverlightApplication1", so the DLL is named "SilverlightApplication1.dll". The rest of the DLL's are the dependancies the application requires.

What is the AppManifest.xaml file?

First lets look at an example AppManifest.xaml file:

[code:xml]

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="SilverlightApplication1" EntryPointType="SilverlightApplication1.App" RuntimeVersion="2.0.30226.2">
  <Deployment.Parts>
    <AssemblyPart x:Name="SilverlightApplication1" Source="SilverlightApplication1.dll" />
    <AssemblyPart x:Name="System.Windows.Controls" Source="System.Windows.Controls.dll" />
    <AssemblyPart x:Name="System.Windows.Controls.Extended" Source="System.Windows.Controls.Extended.dll" />
  </Deployment.Parts>
</Deployment>

[/code]

The first element in the AppManifest.xaml is a Deployment node. This node defines the application and contains child AssemblyPart nodes.

As you can see the AssemblyPart nodes define what assemblies (DLLs) are contained within the .xap file, and give each of them a name.

Now, if you look back up to the top, you'll see the Deployment node has EntryPointAssembly and EntryPointType attributes. The EntryPointAssembly attribute defines which assembly defined below (as a child AssemblyPart node) is the main assembly (DLL) for the application. And, the EntryPointType attribute specifies the Class contained within the assembly (DLL), defined in the EntryPointAssembly attribute, is the main class that will be instantiated to start the application.

The Deployment node also has a RuntimeVersion attribute that defines the version of Silverlight the application is built for.

Conclusion 

There you go, now you have a basic understanding of what an .xap file is. This article was written using Silverlight 2 Beta 1, so things may change in the final release, but I image the basics described here will still remain the same.

I'm sure there are more child nodes and attributes that can be defined within the AppManifest.xaml file, but I have yet to see what they are since, I'm still new to Silverlight 2.0.

Currently rated 4.7 by 7 people

  • Currently 4.714286/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Silverlight
Posted by crpietschmann on Wednesday, March 05, 2008 1:24 PM
Permalink | Comments (3) | Post RSSRSS comment feed

About the author

I'm Chris Pietschmann, go to the About Me page to learn more about me.

Search

Sponsors

Web.Maps.VE - ASP.NET AJAX Virtual Earth Mapping Server Control

Recent comments

Disclaimer


This work is licensed under a Creative Commons Attribution 3.0 United States License, unless explicitly stated otherwise within the posted content.
© Copyright 2004 - 2008 Chris Pietschmann