Categories: Blog

Control Interop, Silverlight-Style

A number of people have asked me in recent weeks whether two Silverlight 2 controls hosted in the same page can communicate with each other, and if so, how. I tell them they need to build a JavaScript bridge between the controls and then the controls can talk to each other just fine.

Tonight I built a sample app to demonstrate. Here’s what it looks like:

 

You drag the red ball in the upper rectangle and the blue rectangle in the lower rectangle mirrors the red ball’s moves. The interesting aspect of this application is that each rectangle represents a different Silverlight control instance. In other words, the page hosts two Silverlight controls, and the red ball lives in one control while the blue ball lives in the other.

Here are the OBJECT tags used to instantiate two Silverlight controls:

<div id=”silverlightControlHost1″>

  <object data=”data:application/x-silverlight,”

    type=”application/x-silverlight-2-b1″ width=”400″

    height=”300″ id=”SourceControl”>

    <param name=”source” value=”ClientBin/InteropDemo.xap”/>

    <param name=”onerror” value=”onSilverlightError” />

    <param name=”background” value=”white” />

  </object>

</div>

   

<div id=”SilverlightControlHost2″>

  <object data=”data:application/x-silverlight,”

    type=”application/x-silverlight-2-b1″ width=”400″

    height=”300″ id=”TargetControl”>

    <param name=”source” value=”ClientBin/OtherControl.xap”/>

    <param name=”onerror” value=”onSilverlightError” />

    <param name=”background” value=”white” />

  </object>

</div>

Each control has its own DIV, and each loads a different XAP file. How did I get Visual Studio to build two XAP files, each containing a separate control assembly? I just added a second Silverlight Application project to the solution. If you already have a Web project in the solution, Visual Studio asks if you want the new project linked to the existing Web project:

Visual Studio obligingly adds the Silverlight project to the solution and configures the build settings so that building the project creates a second XAP file that, like the XAP file from the first project, is copied into the Web site’s ClientBin directory.

To link the two Silverlight controls together, I began by converting the code-behind class for the second control (the one containing the blue ball) into a scriptable class and adding a scriptable method named MoveBall:

[ScriptableType]

public partial class Page : UserControl

{

    public Page()

    {

        InitializeComponent();

        HtmlPage.RegisterScriptableObject(“other”, this);

    }

 

    [ScriptableMember]

    public void MoveBall(double x, double y)

    {

        Ball.SetValue(Canvas.LeftProperty, x);

        Ball.SetValue(Canvas.TopProperty, y);

    }

}

Then I added the following JavaScript function (the “bridge”) to the HTML page:

var _target = null;

   

function moveBall(x, y)

{

    if (_target == null)

        _target = document.getElementById(‘TargetControl’);

    _target.content.other.MoveBall(x, y);           

}

Finally, I added the following statement to the MouseMove handler in the first control (the one with the red ball):

HtmlPage.Window.Invoke(“moveBall”, x, y);

The X and Y coordinates passed in represent the current position of the red ball–the position I just moved it to in response to the latest mouse move.

See how it works? You move the red ball. The MouseMove handler that moves the ball also calls the JavaScript moveBall function, which in turn calls the second control’s MoveBall method. The red ball moves and the blue ball moves, too. This sample takes advantage of Silverlight 2’s rich DOM integration features which allow C# methods to call JavaScript functions, JavaScript functions to call C# methods, and a whole lot more.

I’ll post the source code this weekend. For now, it has been a long week, it’s late, and I’ll be locked away in a hotel all weekend building slides for my Silverlight precon at TechEd and taking care of other jobs that have piled up in my to-do list. Time to get some sleep.

UPDATE: The source code has been posted and you can download it here. In addition, I posted a new version of SilverLife that uses DispatcherTimer rather a Storyboard to drive cell animations. You can download the new version here.

Jeff Prosise

Recent Posts

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

6 days ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago

Mastering Compliance: The Definitive Guide to Managed Compliance Services

In the intricate landscape of modern business, compliance is both a cornerstone of operational integrity…

2 months ago