Let’s Make Money with Silverlight™ Streaming

It’s just quick news for you all. I just recieved MSDN Flash mentioned that we can earn money with Microsoft Silverlight Streaming service. You need to have an account in Microsoft Silverlight Streaming. If you don’t have an account, please click here to create one. Then, you can participate in upcoming Silverlight Streaming contextual advertising pilot. You have to fill up the publisher’s form here and submit it to Microsoft Advertising. If you are selected to participate in the pilot you will be contacted via email.Good Luck!

Congratulations To The Winners of Silverlight 2 “Write and Win” Contest

Hello everybody!!

You all are waiting for the result of our Silverlight 2: Write and Win Contest, isn’t it? Yes, we have five winners. But I’m not gonna announce that news. Oh! Don’t worry! I have invited Ivan Dragoev, Product Manager of SilverlightShow for announcing the winners of our contest. Hello Ivan, Could you please announce the winners of our contest? Thanks!

Silverlight 2: Write and Win Contest

Dear Silverlighter’s,

The Silverlight: Write and Win contest just finished. I would like to say “thank you” to all ten authors for the great articles they submitted and for the courage to show to us, the Silverlight fans and developers, what Silverlight is capable of. We believe, that such contests helps the community to grow and share.

So, having the results of the votes, I’m proud to announce the winners of our contest, the two articles, that have the most votes:

And here are the other 3 articles, randomly selected by us, which will receive Silverlight 2 in Action eBook.

Congratulations!

Ivan

Thanks, Ivan. Congratulations to all winners! I would like to say thank you to everyone who entered and to all of you who voted! I also like to say “thank you” to to Ivan Dragoev and Steven Hong for sponsoring this contest.

Time to vote for Silverlight 2 Contest!

Online voting for “Silverlight 2 “Write and Win” contest” is now closed.

Hello Everyone!

It is time to vote for the winners of our Silverlight: Write and Win contest. The following are the list of great articles that I received for contest.

Silverlight 2 Articles

Please take some time to read those articles and vote your favorite article. Let’s the best win! I would like to say “thank you” to everyone who are participating in this contest. Special thanks to Ivan Dragoev and Steven Hong for sponsoring this contest.

Silveright FlyoutPanel: By Ola Karlsson

Note: This article is submitted by Ola for Silverlight 2 Beta 2 – Articles Competition.Thanks a lot, Ola! Hello All, Please drop a comment if you like it.

Contents

  • Overview
  • First there was creation
  • Blending it up
  • Back to where we started (in VS2008)
  • But I want to see the rest of my XAML UI
  • Take control
  • Two worlds come together
  • Conclusion
  • About the Author (Ola Karlsson)

Download : SL2Beta2FlyoutDemo_SubmissionVer.zip (419KB)

Overview

In this article we’ll be looking at the concept of adding interactive Silverlight elements to existing Web pages to provide added rich features. We’ll be looking at creating an animated Silverlight panel which will slide in from the side of the browser window when a button is clicked.

The somewhat tricky bit is that we want the panel to lie on top on the normal HTML content of the page and when when the Silverlight UI is slid out we want to be able to interact with the HTML instead.
Why did I decide on this topic:

Working as an asp.net developer and having a keen interest for web development in general, I find this way of using Silverlight quite interesting but I have also found that it is not covered very much on the web at the moment.

Concepts and tools we’re using

Tools

  • Visual Studio 2008 with the Silverlight 2 Beta 2 tools installed
  • Blend 2.5 June Preview
  • C#

Concepts

  • Visual State Manager
  • Silverlight/Managed Code – DOM/JavaScript interaction
  • XHTML/CSS
  • Controlling the SL Plugin

First there was creation

First things first, open Visual Studio and create a new Silverlight 2 project/solution to get the full structure including a asp.net test project.

I created a new .Net 3.5, C#, Silverlight project and chose to add a Web Application project to test my Silverlight UI in.

(I only chose “Web Application” because that’s what I’m used to working with, you could as easily use a “Web Site” project.)

Once the IDE has finished loading our new solution, we want to open the page.xaml file in Blend, so we can create the Silverlight UI interface.

Blending it up

In Blend, we now create our Silverlight interface.

For this demo I will simply use the default LayoutRoot grid and change the size to 200×300. However to create the effect we want, we then set the size of the usercontrol to 220×300.

Next drag on a button which we give a size of 20×40, then drag the button into position just outside the upper right corner of the grid. This is probably not the most elegant layout solution but as this article is about browser interaction and animating with Visual State Manager and not about advanced XAML layout, it’s good enough.

As a bit of a nice touch, we’ll make the background a dark semi transparent colour so that one implemented we’ll still be able to see a hint of the HTML content underneath it. To finish our UI, we also drag on a TextBlock, I then gave the controls the amazingly colourful names of “myText” and “myButton”. I also changed the foreground colour and font properties for the TextBlock so it will stand out a bit. This gave me the following:

<UserControl x:Class="SL2Beta2FlyoutDemo.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="220" Height="300"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
<Grid x:Name="LayoutRoot" Background="#35000000" RenderTransformOrigin="0.5,0.5" Width="200" HorizontalAlignment="Left">
<TextBlock Height="35" HorizontalAlignment="Stretch"
Margin="41,42,45,0" VerticalAlignment="Top" FontSize="22"
Foreground="#FFE25B1C" Text="TextBlock" TextWrapping="Wrap"
x:Name="myText" FontWeight="Bold" />
<Button HorizontalAlignment="Right" Margin="0,-1,-20,0"
VerticalAlignment="Top" Content="&amp;amp;gt;" Click="myButton_Click"  x:Name="myButton"
Width="20" Height="40"/>
</Grid>
</UserControl>

Next we move on to use the new Visual State Manager to create our slide out, slide in effect. The Visual State Manger (VSM) is located in the upper left corner and lets us define visual “states” for our UI elements and group these states into “State Groups”. For our UI I defined a State Group called SlideStates and then added two States name Out and In, to it. Note that in VSM there is always a Base State which defines the default state/view in addition to any states you create.

Our next step is to define the base state of our UI, in our case we want create an effect where the UI comes sliding in from the side.

To accomplish this we first select the Base state, then we make sure the correct element is selected (the LayoutRoot grid) and finally we make any necessary adjustments. Since our UI is to slide in from out of view, it needs to start outside the screen, hence we set the x value for the LayoutRoot grid to a minus of its own width (in this case -200). This will set the main section of our UI off the screen but leaves the button on screen.

Next we move on to defining our own states, as the Out state in fact will be the same as the Base state we don’t actually need to make any changes to it.

In the case of the “In” state however, we want the UI to be on screen. As per when we set up the base state, we select the state, then the element and finally make any adjustments. In this case, to bring the LayoutRoot grid back onto the screen we simply set the X value back to 0.

We can now preview the behaviour by clicking on out different states and seeing what happens. However if we were to run this as it currently is, the transition between the states would be pretty much nonexistent, so to get a nice animated transition between the states we use the “Transition Duration” in VSM, here I’ve set it to 0.4 of a second, meaning that, 0.4sec is the time it will take to transition from one state to another.

We could also add more specific transitions of we wanted by using the Add Transition buttons, however for our simply demo, the Default Transition setting works perfectly fine.

Back to where we started (in VS2008)

With those final adjustments in Blend, it’s now time to go back to Visual Studio (VS), so make sure you have saved the changes and go back into VS, when asked if you want to reload the XAML, answer yes. NOTE: When the design surface in VS loads it will display and error message and won’t show the UI we created in Blend, this is a known bug and the good news is that the project will actually still build and when it’s run in the browser it should work fine.

So we now move from the world of XAML into the world of HTML, CSS and JavaScript. For this demo, I’m using the automatically created test page SL2Beta2FlyoutDemoTestPage.aspx, first step is to get the Silverlight plugin on top of the HTML. And to accomplish this we need to edit the default setup somewhat.

We’ll do it in a few steps:

1. To start with I’ve changed the size of the plugin, building a full Silverlight app the size of the Silverlight plugin is usually set to 100% width and height, however if we want to use it together with the HTML, we need to change it to match the actual size of your XAML/Silverlight element. We will also revisit these setting later when creating our slide in, slide out effect. This gives us the following:


<asp:Silverlight ID="Xaml1" runat="server"
Source="~/ClientBin/SL2Beta2FlyoutDemo.xap"
MinimumVersion="2.0.30523" Width="220" Height="300" />

2. Next we add another <div> tag with some HTML content, just after the div that holds the Silverlight plugin. (I’ve also set the background of the page to a gray colour so we can see better what’s happening with our Silverlight plugin).

<body style="height:100%;margin:0;background-color:#CCCCCC">
<form id="form1" runat="server" style="height:100%;">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div id="SLDiv" >
<asp:Silverlight ID="Xaml1" runat="server"
Source="~/ClientBin/SL2Beta2FlyoutDemo.xap"
MinimumVersion="2.0.30523" Width="220" Height="300" />
</div>
<div id="contentDiv" >
<h2 style="text-align:center;">Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam vestibulum lacinia tortor eros.</p>
<p>Sed ornare ullamcorper lacus. Ut vel risus. Vestibulum laoreet ligula et, per inceptos himenaeos. Nulla ipsum. Nullam metus. </p>
<p>Sed nisl nisi, sagittis non, ullamcorper ac, . Aliquam erat volutpat. In hac habitasse platea dictumst. Nunc vehicula enim et justo. </p>
</div>
</form>
</body>

All this will do however is to add some Content text on the page after our Silverlight plugin. You can note thought that we now can see the first part of “out” UI on the page!

3. To actually get the Silverlight area on top of the other content we turn to the power of CSS, and make the following changes:

<div id="SLDiv" style="position:absolute; left:0; top:0; z-index:2;">
<div id="contentDiv" style="position:absolute; top:0; left:0; z-index:1;">

Basically, we’re using CSS to lock the two divs in absolute positions and then we use the z-index attribute to layer them on top of each other (higher number = higher up in the stack). These changes give us quite a different result, where the Silverlight plugin is layered on top of our HTML content.

Now some of you might be saying, “Hey, what happened the transparency we set back in Blend?”
Well, what we did in Blend was that we set the XAML to be semi transparent, but to get the actual plugin transparent there’s a couple of things we need to change in how we set up the plugin on our page. Namely we need to add the two new parameters, Windowless and PluginBackground to the Silverlight control:


<asp:Silverlight ID="Xaml1" runat="server"
Source="~/ClientBin/SL2Beta2FlyoutDemo.xap"
MinimumVersion="2.0.30523" Width="220" Height="300"
Windowless="true" PluginBackground="Transparent" />

If we now run our page again, you should find that the Silverlight plugin area is no longer visible, so where’s our UI? Well all is as it should, as you might recall, the base state for our XAML UI is actually to start off page, hence we can’t see it!

However, to make things a bit easier for ourselves while working with the plugin, we’ll change the PluginBackground to Black for now, so we can see the plugin area.

But I want to see the rest of my XAML UI

Ok fair enough, this is all very exciting but I’m sure by now most of you want to see if this actually works?!
Lets get coding! So to prove to you that this actually works, we’ll go over to VS and open up the code behind file for our XAML file “Page.xaml.cs”. Just as a quick test we make the following change to the Page method:

public Page()
{
InitializeComponent();
VisualStateManager.GoToState(this, "In", true);
}

All this does is that it tells the VSM, that our current control (this) should go to the state “In”, the final boolean value decides whether a transition should be used. If you now go ahead and compile the solution and run the  page, you should see our XAML UI slide in from the left hand side in all its glory! (Minus the transparency of course but we’ll get back to that later)

So how do we control this? We don’t want it coming in when the page loads! Well for that we need to go back into code land.

Take control

Step one of taking control of our animated UI is to create a new event handler for out button, open the XAML view of Page.xaml, in the tag for the button, add a Click event:

Next right click on the new event and select “Navigate to Event Handler”, this will take us into the code behind file straight to the newly created event handler. Once there, simply move the line for the VSM interaction from the Page method into the new event handler. In the code behind make the changes to make it look like the following code:

public partial class Page : UserControl
{
String state;
public Page()
{
InitializeComponent();
state = "out";
}
private void myButton_Click(object sender, RoutedEventArgs e)
{
if (state == "out")
{
VisualStateManager.GoToState(this, "In", true);
state = "in";
myButton.Content = "<";
}
else
{
VisualStateManager.GoToState(this, "Out", true);
state = "out";
myButton.Content = ">";
}
}
}

Basically we’ve set up a variable to hold the current state of the control, then we’re using the Click event handler to slide the UI in or out based on the value in out variable. Just as an extra touch I also change the content (text) of the button to reflect which direction it will go when clicked.

So if we now set the PluginBackground to Transparent, we’re done right?!

We’ll, almost, the problem we’ll run into with our project that way it is currently. Is pretty plain to see while we don’t have the PluginBackground set to Transparent, as the Silverlight plugin is layered on top of our HTML, it stops us from interacting with the HTML below. Setting the PluginBackground will let us see what’s underneath, but as I’ve been pointing out to people when discussing these kind of implementations, just because you can see it doesn’t mean you can click it!

So how do we solve this problem? In steps JavaScript to save the day!

Two worlds come together

To solve this issue, we’ll use JavaScript to change the size of the Silverlight plugin container.

First we need to make a couple of adjustments to the Silverlight plugin tag, we’re adding a OnPluginLoaded event which I’ve set up to call the JavaScript function “PluginLoaded”. That function will be used to get a JavaScript reference to the Silverlight plugin object.

We also set the width of the plugin to 20(the width of our button), this so that our button appears but the rest of the Silverlight area isn’t hindering us from interacting with the HTML. As we’re not changing the height there will be a narrow strip left but if we really wanted to we’d just change that as well.

Next we go into our Page.xaml.cs file and add a “using System.Windows.Browser; ” then modify our Click event handler to what’s shown below.

Then once we have the System.Windows.Browser using statement in place, we can use HTMLPage.Window to get a reference to the browser window and thereby interact with it from our managed code!  CreateInstance, simple calls and executes the JavaScript methods defined.

private void myButton_Click(object sender, RoutedEventArgs e)
{
if (state == "out")
{
VisualStateManager.GoToState(this, "In", true);
HtmlPage.Window.CreateInstance("GrowHorisontal");
state = "in";
myButton.Content = "<";
}
else
{
VisualStateManager.GoToState(this, "Out", true);
state = "out";
myButton.Content = ">";
HtmlPage.Window.CreateInstance("DelayedShrink");
}
}

Next step is to add the necessary JavaScript functions to the header section of out aspx page:

<head runat="server">
<script type="text/javascript">
var slCtl = null;

function pluginLoaded(sender)
{  // Get a refernce to the Silverlight plugin when the page loads
slCtl  = sender.get_element();
}
function GrowHorisontal()
{
//Grow the width
slCtl.style.width='220px';
}
function DelayedShrink()
{
//Delay the call to the actual shrink function to let the animation finish before shrinking the area
setTimeout(ShrinkHorisontal, 500);
}
function ShrinkHorisontal()
{  //Shrink the area
slCtl.style.width='20px';
}
</script>
<title>Test Page For SL2Beta2FlyoutDemo</title>
</head>

Pheew, well good news is we’re almost done!

The only real thing that remains is to set the PluginBackground to Transparent and we’re done, if you’ve made it this far, give yourself a pat on the shoulder from me, well done for sticking with it. :)

The final thing I did was to set the background colour of the HTML body back to white to better see the Silverlight UI.

Conclusion

Using the new Visual Sate Manger we were able to very easily create a animated Silverlight and using JavaScript and CSS we dynamically slid the Silverlight on top of the HTML without hindering interaction with the HTML.
References:

About the Author (Ola Karlsson)

After a misspent past as a scuba diving instructor in various places around the world. This blue eyed, blond, 6,2” Swede is now living and working in the land down under as a full time Asp.Net developer for a medium sized Microsoft Gold Certified Partner specialising in Moss and custom Asp.Net solutions.

Silverlight and Flash Interoperability using HTML Bridge and ExternalInterface API: By Jonas Follesø

Note: This article is submitted by Jonas for Silverlight 2 Beta 2 – Articles Competition.Thanks a lot, Jonas! Hello All, Please drop a comment if you like it.

Contents

  • Introduction
  • Flash ExternalInterface API
  • Silverlight HTML Bridge
  • Calling Flash from Silverlight
  • Calling Silverlight from Flash
  • Silverlight web cam support using Flash interoperability
  • Summary

Download :SilverlightFlashIntegrationWeb.zip (1.43  MB)

Introduction

Silverlight and Flash have many similarities. Both are browser plug-ins that enables web developers to build richer internet applications. You can choose to have Silverlight or Flash occupy the entire screen and build all off the application, or you can have Silverlight or Flash embedded as small islands on your HTML page.
When you decide to include Silverlight or Flash on your page there are many scenarios where you may want to enable the application to interact with the rest of your page. You may want to read data from the HTML page, or update certain HTML elements at runtime. Perhaps you are gradually enhancing an existing web application and need to leverage existing JavaScript code running on the page. In these scenarios you need to leverage the browser integration model supported by Silverlight or Flash to communicate between your application and the hosting HTML page.

In this tutorial I’ll walk you through the basics of browser integration, and how you can make Silverlight and Flash talk to each. The tutorial starts off with some basic examples of browser integration in Flash and Silverlight, and move on to show how to enable webcam support in Silverlight using Flash.

Flash ExternalInterface API

Flash has been around for a long time and there have been different techniques to communicate between Flash and the. The “Flash JavaScript Integration Kit” is one example of such a framework. In Flash 8 Adobe included an official API to enable integration between your Flash application and the browser called the “ExternalInterface API”. The API consists of two main functions: the “addCallback” function to expose an ActionScript function to the web page, and the “call” function to invoke JavaScript functions on the web page.

The following code shows how to create a simple ActionScript function and expose it using the ExternalInterface API:


ExternalInterface.addCallback("saySomething", saySomething);

function saySomething():String
{
return "Hi, I'm Flash!";
}

To call the function from JavaScript you need to get a reference to the Flash player on the HTML page, and simply call the “saySomething” function:


function callFlash()
{
// Get a reference to the player
var player = null;

if (document.all)
player = document.all("flashPlayer");
else
player = document.getElementById("flashPlayerEmbedded");

alert(player.saySomething());
}

If you want to call a JavaScript function from ActionScript you simply use the “call” function on the ExternalInterface API:

function clicked(eventArgs:Object):void
{
ExternalInterface.call("saySomething", "What's up? I'm calling from Flash!");
}
this.btnSave.addEventListener("click", clicked);

Off course you also need to have the “saySomething” JavaScript function defined on your page:

function saySomething(something)
{
alert(something);
}

As you can see the ExternalInterface API makes it really easy to communicate between Flash and the browser. This first example use simple strings as parameters, but you can pass any ActionScript type across the ExternalInterace API. That being said, in many cases passing strings is all you need as you can format your data using JSON or XML.

Silverlight HTML Bridge

The browser integration layer in Silverlight 2 is often called the “HTML Bridge”, and enables you to interact with both HTML elements as well as JavaScript code running in the browser. This opens up for several interesting integration scenarios, some not even using Silverlight for the user interface at all.
At the core of the HTML bridge is the “ScriptObject”, which objects such as HtmlObject, HtmlPage, and HtmlElement derive from. To invoke the “saySomething” function from our previous example you simply write:


HtmlPage.Window.Invoke("saySomething", "Can you see the light? The Silverlight!");

The HTML bridge contains a lot of functionallity in addition to basic function invocation. It contains functionalliy to grab a HTML DOM Element and change it’s properties and style attributes. You can expose .NET types to the JavaScript runtime and then create new instances of the type from JavaScript. You can also expose instances of .NET objects to the JavaScript and directly interact with the object.

For a good introduction to interaction between HTML and managed code I recommend checking out the Silverlight quick starts at http://www.silverlight.net/QuickStarts/Dom/. The focus on this article will be on Silverlight 2 to Flash integration, and will not go in-depth on the Silverlight HTML Bridge.
Calling Flash from Silverlight

The Flash ExternalInterface API and the Silverlight HTML gives us the building blocks we need to start passing data between a Silverlight 2 and Flash application running on the same page. For this example we’re going to create a simple user interface to edit a person in both Flash and Silverlight. The interface looks something like this:

Calling Flash from Silverlight

The Flash ExternalInterface API and the Silverlight HTML gives us the building blocks we need to start passing data between a Silverlight 2 and Flash application running on the same page. For this example we’re going to create a simple user interface to edit a person in both Flash and Silverlight. The interface looks something like this:

In the example I want to show how to call Flash from Silverlight, and Silverlight from Flash. We’ll start by covering how to read a Person object from Flash into Silverlight when the user clicks the “Load from Flash” button.

The first thing we need to is create an ActionScript function to get a Person object from the Flash application. Both JavaScript and ActionScript are following based on the ECMAScript specification, and support object literals. This is a straight forward syntax to create new objects on the fly. For more information check out object literals in ECMAScript check out http://en.wikipedia.org/wiki/Object_literal.

ExternalInterface.addCallback("getPerson", getPerson);
function getPerson():Object
{
return { name: txtName.text, email: txtEmail.text, url: txtUrl.text };
}

The object returned contains three properties, name, email and url. To get the object from Flash into Silverlight we use a little JavaScript helper function:

function loadFromFlash()
{
var flash = getFlash();
if(flash)
{
return flash.getPerson();
}
}

The final piece is the C# code to handle the button click and call the JavaScript helper function. The code calls the JavaScript function and gets a generic ScriptObject back. This object contains a ConvertTo-method that tries to convert a script object to a .NET type. To hold the person data we’ve created a simple .NET person object. The property names have to match in order for the conversion to successes:

public class Person
{
public string name { get; set; }
public string url { get; set; }
public string email { get; set; }
}
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
ScriptObject scriptObject =
(ScriptObject)HtmlPage.Window.Invoke("loadFromFlash");

var person = scriptObject.ConvertTo<Person>();
txtName.Text = person.name;
txtEmail.Text = person.email;
txtUrl.Text = person.url;
}

When we run the application we can enter data in the Flash application, and hit the “Load from Flash” button to update the Silverlight application. The next step is the “Save to Flash” functionality. When the user clicks the “Save to Flash” button we want to push the .NET object from Silverlight to Flash. The HTML bridge supports passing .NET objects from Silverlight to JavaScript by marking an object as scriptable:

[ScriptableType]
public class Person
{
[ScriptableMember]
public string name { get; set; }

[ScriptableMember]
public string url { get; set; }

[ScriptableMember]
public string email { get; set; }
}

Once the type is marked as scriptable we can pass it to any JavaScript function invoked using the HTML bridge. In theory we should be able to pass this type along to Flash, but for some reason the Flash plug-in is throwing an exception when you try passing it a scriptable type. There are several possible workarounds. One option is to pass the object to JavaScript, and then write JavaScript code to create a new object before passing on to Flash. Another option is to use the Silverlight JSON serializer and pass the object as a JSON-string to the JavaScript function, and then evaluate the string before passing it as a JavaScript object to Flash. I’ve included sample code for both solutions.

The first option is to pass the object directly to the JavaScript function, and then create a JavaScript object on the fly before passing it to Flash:

private void btnSave_Click(object sender, RoutedEventArgs e)
{
var person = new Person();
person.name = txtName.Text;
person.email = txtEmail.Text;
person.url = txtUrl.Text;
HtmlPage.Window.Invoke("saveToFlash", person);
}

The “saveToFlash” function creates a new JavaScript object before passing it along to Flash. The optimal solution would be to pass the object straight to Flash:

function saveToFlash(person)
{
var flash = getFlash();
if(flash)
{
var jsPerson = {
name: person.name,
email: person.email,
url: person.url
};
flash.setPerson(jsPerson);
}
}

The ActionScript function to update the Flash UI is really straight forward:

ExternalInterface.addCallback("setPerson", setPerson);

function setPerson(person:Object):void
{
txtName.text = person.name;
txtEmail.text = person.email;
txtUrl.text = person.url;
}

The second approach for passing our Person object from Silverlight to Flash is to serialize it to JSON before passing it to the browser. JSON stands for “JavaScript Object Notation”, and is a way to represent a full object graph as a string. Basically it’s just a string containing object literals, which can be evaluated by the JavaScript engine to build an object three. Silverlight has built-in support for JSON serialization, so implementing this is fairly straight forward. We’re going to use the DataContractJsonSerializer class, which is located in the System.ServiceModel.Web assembly under the System.Runtime.Serialization.Json namespace. We also need to reference the System.Runtime.Serialization assembly to get the DataContract and DataMember attributes we need to tag our Person object with.

After adding the DataContract and DataMember attributes our Person object now looks like this:

[DataContract]
public class Person
{
[DataMember]
public string name { get; set; }

[DataMember]
public string url { get; set; }

[DataMember]
public string email { get; set; }
}

Using C# 3.5 extension methods you attach a “ToJson”-method to all objects for an easy way to serialize any object. An extension method is basically a public static method in a static class, where the first parameter has the “this” keyword:

public static class Extensions
{
public static string ToJson(this object obj)
{
using(MemoryStream ms = new MemoryStream())
{
DataContractJsonSerializer serializer = new
DataContractJsonSerializer(obj.GetType());

serializer.WriteObject(ms, obj);
ms.Position = 0;
using(StreamReader reader = new StreamReader(ms))
{
return reader.ReadToEnd();
}
}
}
}

So in order to pass the JSON –serialized Person object to our JavaScript function we simply need to call the “ToJson” method on the person object:

private void btnSave_Click(object sender, RoutedEventArgs e)
{
var person = new Person();
person.name = txtName.Text;
person.email = txtEmail.Text;
person.url = txtUrl.Text;
HtmlPage.Window.Invoke("saveToFlash", person.ToJson());
}

We only need a minor change in the JavaScript function, where we evaluate the JSON string to build a JavaScript object we can pass to Flash:

function saveToFlash(person)
{
var flash = getFlash();
if(flash)
{
var jsPerson = eval('(' + person + ')');
flash.setPerson(jsPerson);
}
}

Calling Silverlight from Flash

So far we’ve covered how to call ActionScript functions from Flash. Now we want to do the opposite, call Silverlight functions from ActionScript. The first thing we want to implement is the “Load from Silverlight”-button. When the user clicks the button in Flash we want to call Silverlight to get our Person object. To do that we add a new method to your Silverlight application, as well as mark the user control as a scriptable type, and the method as a scriptable member:

[ScriptableType]
public partial class Page : UserControl
{
[ScriptableMember]
public string GetPerson()
{
var person = new Person();
person.name = txtName.Text;
person.email = txtEmail.Text;
person.url = txtUrl.Text;
return person.ToJson();
}
// Additonal code removed from example...
}

We also need to expose an instance of the user control to the browser so that we can call the GetPerson-method from JavaScript:

public Page()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("Page", this);
}

The next thing we need to do is to create a JavaScript function to be called from Flash to get the Person object from Silverlight:

function loadFromSilverlight()
{
var silverlight = getSilverlight();
if(silverlight)
{
var jsPerson = eval('(' + silverlight.content.Page.GetPerson() + ')');
return jsPerson;
}
}

To call the Silverlight method we get an instance of the Silverlight control and then access its content property. For each object we’ve registered as scriptable we can access it based on its key. The Page was registered with the key “Page”, so to syntax to call the GetPerson-method looks like this:

silverlight.content.Page.GetPerson()

The final step is to add the ActionScript code to handle the Flash button click event and call the JavaScript function:

function loadClicked(eventArgs:Object):void
{
var person = ExternalInterface.call("loadFromSilverlight");
txtName.text = person.name;
txtEmail.text = person.email;
txtUrl.text = person.url;
}
this.btnLoad.addEventListener("click", loadClicked);

Now that we can load from Silverlight to Flash we want to be able to save. The steps involved should be familiar by now. We start by adding a scriptable method on the Silverlight page:

[ScriptableMember]
public void SetPerson(ScriptObject scriptPerson)
{
var person = scriptPerson.ConvertTo<Person>();
txtName.Text = person.name;
txtEmail.Text = person.email;
txtUrl.Text = person.url;
}

The only important thing is the parameter type. We accept a ScriptObject which we convert to a Person object, before updating the UI. We also need to add some JavaScript to call from Flash:

function saveToSilverlight(person)
{
var silverlight = getSilverlight();
if(silverlight)
{
silverlight.content.Page.SetPerson(person);
}
}

In this example there is no type conversion, we’re passing the ActionScript person object straight to the SetPerson-method. We also need to add a click event handler for the Flash button:

function saveClicked(eventArgs:Object):void
{
ExternalInterface.call("saveToSilverlight",
{
name: txtName.text,
email: txtEmail.text,
url: txtUrl.text
});
}

Again we use object literals to create an on-the-fly person object that we pass to the JavaScript function.

Silverlight web cam support using Flash interoperability

Now that we’ve seen how we can integrate Silverlight and Flash using the HTML Bridge and ExternalInterface API it’s time to do something (somewhat) useful. We’re going to enable some basic webcam support in Silverlight using Flash interoperability.

Even though Flash and Silverlight have much of the same functionality, there are certain things you cannot do on both platforms. Local access of webcam and microphone is one example of something that is only possible in Flash. The way webcams work in Flash is through a camera–object. You attach the camera object to a video-object do display the video stream. The ActionScript code to create a camera and video looks like this:


var cam:Camera = Camera.getCamera();
cam.setMode(320, 240, 12);
var video:Video = new Video(320, 240);
video.attachCamera(cam);
this.addChild(video);

When you run your Flash application you’ll see a dialog asking if you want to give permission to access webcam and microphone. If you give the permission the video from your webcam should show on your screen.

With the video showing on screen, the next step is to add expose some ActionScript functions to take a snapshot of the video, and send the snapshot back to Silverlight. Flash supports drawing a frame from the video-object into a BitmapData-object. Using the open source as3corelib ActionScript extensions we can use a PNG-encoder to encode the BitmapData into a byte array. This byte array can be encoded as a Base64 string and passed to the browser using the ExternalInterface API:


import com.adobe.images.PNGEncoder;
import com.dynamicflash.util.Base64;

flash.system.Security.allowDomain("*");
ExternalInterface.addCallback("takeSnapshot", takeSnapshot);

function takeSnapshot():String
{
var bmd:BitmapData = new BitmapData(video.width, video.height,
false, 0x00CCCCCC);
bmd.draw(video, new Matrix());

var pngBytes:ByteArray = PNGEncoder.encode(bmd);
return Base64.encodeByteArray(pngBytes);
}

Using the code above we have a way to call our Flash application to get a Base64 encoded PNG image as a string. This string can be passed to Silverlight, which can decode the Base64 data into a byte array, and load the PNG image into a BitmapImage that can be used as the source of a Silverlight Image control. The JavaScript function to call Flash and pass the string back is really simple:

function takeSnapshot()
{
var flash = getFlash();
if(flash)
{
return flash.takeSnapshot();
}
}

The click event handler for the “take snapshot”-button calls the JavaScript function to get the Base64 encoded PNG image, decode it and set it as the source of a Silverlight image control:

void btnTakeSnapshot_Click(object sender, RoutedEventArgs e)
{
string base64Image = (string)HtmlPage.Window.Invoke("takeSnapshot");
if (base64Image != string.Empty)
{
byte[] imageData = Convert.FromBase64String(base64Image);
MemoryStream ms = new MemoryStream(imageData);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
ms.Dispose();

snapshot.Source = bitmapImage;
}
}

Silverlight supports both JPG and PNG images, and the image returned from Flash is PNG encoded. All we have to do on our side is turn the Base64 string into a byte array, load it into a MemoryStream, and then load the MemoryStream into a BitmapImage. A BitmapImage can be used as the source for any Silverlight Image control.

Now that we got the PNG image in Silverlight we can do what ever we want with it. We can upload it to the server, we can use it in Silverlight animations, or perhaps for cassual games like a sliding photo puzzle.

Summary

Both Silverlight and Flash have APIs to bridge between the plug-in and the browser. Using this you can make Flash and Silverlight talk, using JavaScript as the bridge between the technologies. I hope this tutorial has given you a good introduction to both Silverlight and Flash browser integration, and how it can be used to bridge the technologies. The webcam example shows how we can use this technique to achieve something quite interesting. This is by no mean a substitute for a proper webcam API in some future Silverlight version, but it gives you some basic webcam support you can play with. I will definitely be posting more about webcam support in Silverlight, and some examples of what you can use it for.

All the code is included with this article, and is licensed under the MS-Pl license. The article is copyrighted under the creative commons license.

Connecting Drupal and Silverlight: By Matt Serbinski

Note: This article is submitted by Matt Serbinski for Silverlight 2 Beta 2 – Articles Competition.Thanks a lot, Matt! Hello All, Please drop a comment if you like it.

Connecting Drupal and Silverlight
Connecting Drupal and Silverlight

Contents

  • Introduction
  • Custom Module for Drupal
  • Silverlight application
  • About the Author (Matt Serbinski)

Download ~

Introduction

Drupal is an open source content management system (CMS) that allows users to add modules to their sites for great flexibility. These modules are typically written in PHP and use drupal’s API to connect themselves with the framework. Silverlight (version 2.0 and greater) is a cross-platform browser plugin that allows users to write managed .NET code for the back end and use XAML as the front end. Since silverlight is a browser application and drupal is a framework for hosting data in browsers there can be data that is shared between the two using HTTP as the transport. In this example, I have chosen to use XML-RPC as drupal uses xml-rpc natively and silverlight can easily take advantage of this.

XmlRPC
XmlRPC

One thing to note, drupal has a module called services that is currently under development that will allow external applications (such as silverlight) to easily communicate through various interfaces, such as: XML-RPC, SOAP, REST and AMF. I am NOT using this module in my example.

Custom Module for Drupal:

As far as the drupal side of things go, I have a basic install of drupal 6.2 with a custom module that I have written to communicate with my silverlight application. I wrote the module based off of tips from Pro Drupal Development using chapters 2 and 19. There are two files that are needed to construct a drupal module: a .info file that contains information about the module and a .module file that is the actual custom module. My custom module is extremely simple in which it implements hook_xmlrpc to map xml-rpc methods to php callback functions. The xml-rpc methods are received from silverlight and then call the appropriate php function with the appropriate arguments. My php functions do various tasks, such as: checking the drupal database to see if a user exists so that user can login if the correct credentials are supplied,logging in an anonymous user, logging a user out and creating a fully authenticated user. Once the module is uploaded to the server, enable the module and your done! Well, done with the drupal side.

Silverlight application

There are currently two methods in silverlight to communicate via a web service (in this case xml-rpc): WebClient and HttpWebRequest. HttpWebRequest contains all of the properties and methods that WebClient has and then some. But of course the extra goodies that HttpWebRequest provides come at a price; added complexity. WebClient is extremely easy to use and only requires one event and one property to be used, all though there are additional events and properties that can make life easier. Here are the events and properties that I have used in my application:

drupalDB = new WebClient();
drupalDB.UploadStringCompleted += new UploadStringCompletedEventHandler(drupalDB_UploadStringCompleted);
drupalDB.UploadProgressChanged += new UploadProgressChangedEventHandler(drupalDB_UploadProgressChanged);
drupalDB.UploadStringAsync(location, xmlData);

drupalDB is my WebClient and there are two events defined that will notify me when upload progress has changed (perfect for a progress bar) and completed. The property, UploadStringAsync takes in a Uri and a string as the data to upload to the web service. One thing to note here is that I am using UploadStringCompleted and not DownloadStringCompleted as WebClient does a GET for downloads and a POST for uploads and xml-rpc only accepts POSTs.

The data that I am uploading to the xml-rpc service is a string that is xml formatted that uses the standard xml-rpc definition:

</p></p>

string xmlData = "<?xml version=\"1.0\"?>"
+ "<methodCall>"
+ "<methodName>userlogin.logAnonIn</methodName>"
+ "<params>"
+ "<param>"
+ "<value>"
+ "</value>"
+ "</param>"
+ "</params>"
+ "</methodCall>";

There are two important things to note here. The tag <methodName> contains the xml-rpc method that the hook_xmlrpc function will map to a php function. The first part of that argument, userlogin is the name of my module and a standard format that drupal follows. The <param> tag contains a <value> tag where an argument can be passed to the hook_xmlrpc function. If multiple arguments are required then one needs to add additional <param><value>my data here</value></param> tags in between the <params> tag. Once the data is sent from silverlight to drupal and the appropiate mapping php function is processed, a return value is sent back to silverlight:

<methodResponse>
<params>
<param>
<value>
<string>return value</string>
</value>
</param>
</params>
</methodResponse>

The UploadStringCompleted event will fire once all of the above data is received. A popular way to parse the returned data is to use LINQ. LINQ is very powerful and very easy to use once you learn a little about it. I can parse the above data with the following LINQ statement:

</p></p>

XDocument document = XDocument.Parse(e.Result);
List<MethodToCall> methodsToCall = (from user in document.Descendants("value").Elements("string")
select new MethodToCall
{
MethodName = user.Value
}).ToList();

I place the result in an XDocument and use LINQ to parse the document for any node ‘value’ that has a child node ‘string’. This is the standard format that xml-rpc sends. If there are mutliple arguments then there will be multiple ‘value’ nodes. I call ToList() on the LINQ statement to create a generic list for multiple arguments that may be passed back.

With my particular application, since I can control what I send to and from the xml-rpc service, I decided to use reflection and pass back a string from drupal that I have defined as a method in my silverlight application. One thing to note here is that arguments are passed back as objects. If multiple arguments are passed back they are each an object, not an object[] so your method must take multiple arguments that are each objects instead of one argument of type object[].

After my method is called via reflection I simply update my user object as appropriate. And that’s it! That is the basics of how to get drupal to talk to silverlight and vice versa. Of course, one needs to add some more logic and flare to a silverlight application to take advantage of the data it receives from drupal. I have added a few items that hopefully make the user experience that much better (and easier) in my user login application.

As a side note, once silverlight is configured on your web server all you need to display the silverlight application is the following html code placed wherever you would like:

</p></p>

<div style="width: 325px; height: 350px;">
<object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%">
<param name="source" value="/silverlight/SLApps/DrupalGameDemo.xap" />

<!-- Only need the below to show a link to get silverlight if it is not installed -->
<a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" />
</a>
</object>
</div>

The <object> tag contains a <param> tag that has the ‘value’ attribute of the location of your .xap file. The link in the above html code (<a> tag) is the link that will be displayed if a user does not have silverlight installed.

Feel free to try out the attached silverlight application (it is also displayed at the top of this page) and change things to your liking. Enjoy!

About the Author (Matt Serbinski)

My name is Matt Serbinski and I graduated from Rochester Institute of Technology (RIT) in March 2007 with a BS in computer engineering. I have been working at my current job, Naval Surface Warfare Center in Dahlgren, Virginia since 2004 while I was cooping. I have worked on a handful of projects that integrate existing technologies (lethal and non lethal) onto vehicle platforms as a single point to control everything. I was introduced to WPF when it was in beta and started to love everything it offered. Once Silverlight 2.0 was in beta I started to develop applications on the side for fun. I enjoy taking technologies and figuring out ways to use them together and developing WPF and Silverlight applications for fun.