DCSIMG
July 2008 - Posts - Alex Golesh's Blog About Silverlight Development

July 2008 - Posts

Quick Silverlight Tip: Silverlight Events in JavaScript and JavaScript Events in Silverlight

Lately I've been asked couple of times about catching managed events in JavaScript and catching JavaScript events in Silverlight managed code.

In fact it is very easy, but seems not so obvious... Here it goes.

To catch JavaScript event in Silverlight managed code, all your application need to do is to "attach" to event from some HtmlElement you have on hosting page and define some managed EventHandler to handle the event.

Sample page as it was auto generated by Visual Studio 2008, MyApplicaitionTestPage.html. All I added to this test case is HTML button:

   1: <input id="Button1" type="button" value="Test"/></p>

Now, in my code behind class I defined function, which will handle the event:

   1: void JsButtonEventHandler(object sender, EventArgs e)
   2: {
   3:     //Just prints notification in some TextBlock
   4:     txtOutput.Text += "Got event from = " + (sender as HtmlElement).Id.ToString() + "\n";
   5: }

and subscribed to HTMLElement event. This could be done anywhere in code; I did it in class constructor:

   1: //Class ctor
   2: public Page()
   3: {
   4:     InitializeComponent();
   5:     
   6:     //Subscribe to event 'onclick' 
   7:     HtmlPage.Document.GetElementById("Button1").AttachEvent("onclick", new EventHandler(JsButtonEventHandler)); 
   8: }

That's it - now we can receive events from HTML elements in our Silverlight application

image image

Now let's extend this sample, and subscribe in JavaScript to some events from Silverlight.

First of all, I need to put "[ScriptableType]" attribute to my class and "[ScriptableMember]" attribute to my event. Actually, I need to put "[ScriptableType]" attribute to all data types I'd like to work with in JavaScript. Then I need to register the instance to be accessible from script.

Last thing I'm doing in this sample is events fire as a reaction on Silverlight mouser click event.

Here is my my super simple XAML page:

   1: <UserControl x:Class="SilverlightApplication7.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     Width="400" Height="300">
   5:     <Grid x:Name="LayoutRoot" Background="Yellow">
   6:         <TextBlock x:Name="txtOutput" Width="400" Height="300"/>
   7:         <Button Content="test" Width="100" Height="25" Click="Button_Click"/>
   8:     </Grid>
   9: </UserControl>

And here is my complete class:

   1: //Register whole type as accessible from script
   2: [ScriptableType]
   3:  public partial class Page : UserControl
   4:  {
   5:      //Register the custom event to be as accessible from script
   6:      [ScriptableMember]
   7:      public event EventHandler<CustomEventHandler> ServiceCallFinished;
   8:  
   9:      //Register the simple event to be as accessible from script
  10:      [ScriptableMember]
  11:      public event EventHandler SomeEvent;
  12:  
  13:      public Page()
  14:      {
  15:          InitializeComponent();
  16:  
  17:          //Register this instance to be accessible from script
  18:          HtmlPage.RegisterScriptableObject("SilverlightApp", this);
  19:  
  20:          HtmlPage.Document.GetElementById("Button1").AttachEvent("onclick", new EventHandler(JsButtonEventHandler));
  21:      }
  22:  
  23:      private void Button_Click(object sender, RoutedEventArgs e)
  24:      {
  25:          //Fire test events on Silverlight button click
  26:          FireEvent("Test Event from Silverlight");
  27:          FireSimpleEvent();
  28:      }
  29:  
  30:      private void FireEvent(string output)
  31:      {
  32:          if (null != ServiceCallFinished)
  33:              ServiceCallFinished(this, new CustomEventHandler() { WCF_Output = output });
  34:      }
  35:  
  36:      private void FireSimpleEvent()
  37:      {
  38:          if (null != SomeEvent)
  39:              SomeEvent(this, new EventArgs());
  40:      }
  41:  
  42:      void JsButtonEventHandler(object sender, EventArgs e)
  43:      {
  44:          txtOutput.Text += "Got event from = " + (sender as HtmlElement).Id.ToString() + "\n";
  45:      }
  46:  }
  47:  
  48: //Class for sending custom event arguments
  49: [ScriptableType]
  50: public class CustomEventHandler : EventArgs
  51: {
  52:     public string WCF_Output { get; set; }
  53: }

Now let's see how I subscribe to those events in BLOCKED SCRIPT

I'm subscribing to "onload" event for Silverlight object, and in "onload" handler function subscribe to JavaScript events. Here is my Silverlight object DIV

   1: <div id="silverlightControlHost">
   2:     <p>WCF call results:</p>
   3:     <p><textarea id="TextArea1" cols="40" rows="5" width="400"></textarea></p>
   4:     <p>
   5:     
   6:     <input id="Button1" type="button" value="Test"/></p>
   7:     
   8:     <object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="50%" height="50%" id="SilverlightObject">
   9:         <param name="source" value="ClientBin/SilverlightApplication7.xap"/>
  10:         <param name="onerror" value="onSilverlightError" />
  11:         <param name="background" value="Gray" />
  12:         <param name="onload" value="OnLoaded" />
  13:         
  14:         <a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
  15:              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
  16:         </a>
  17:     </object>
  18:     <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
  19: </div>

and here is my JavaScript for OnLoaded function and event handler functions:

   1: function OnLoaded(sender, args)
   2: {
   3:     //Getting Silverlight object on page
   4:     var silverlightControlHost = document.getElementById("SilverlightObject");
   5:     //Subscribe to it events
   6:     silverlightControlHost.Content.SilverlightApp.ServiceCallFinished = ServiceCallFinished;
   7:     silverlightControlHost.Content.SilverlightApp.SomeEvent = SomeEvent;
   8: }
   9:  
  10: //General event handler function
  11: function SomeEvent(sender, e)
  12: {
  13:     alert("Some general Silverlight event received!");
  14: }
  15:  
  16: //Event handler for event with customized EventArgs 
  17: function ServiceCallFinished(sender, result)
  18: {
  19:     document.getElementById("TextArea1").value += "\n" + result.WCF_Output;
  20: }

The result works as expected:

image

I hope this covers all scenarios on how subscribe to events between HTML/JavaScript and Silverlight.

 

Enjoy,

Alex

Quick Silverlight Tip: "InitializeError #2103 - Invalid or malformed application" what is it and how to deal with it?

Today I've seen very strange and unpleasant error while trying to run some freshly created Silverlight application. It said:

Code# 2103

Invalid or malformed application: Check manifest

Fast search by popular search engines gave me this and this places, but everything mentioned there I've already knew or tried before... So what is it? Let's see what it was and how it was solved. Let's reproduce it.

 

I'm creating new Silverlight 2 project, compiled it it works... My simplest project looks like follows (every button click just adds "!" to Button.Content):

image image

Everything works fine, until I decided to change the namespace in your class.

When changing the namespace in you Page.xaml.cs don't forget to change it also in Page.xaml, App.xaml.cs and App.xaml. This is known, and I did it.

After compiling and lunching the application I received this:

image (if I used <asp:Silverlight/> in a ASP.NET page)

or this:

image (if used <object/> in a HTML page)

Why it happened?

I did the change in all files, I recompiled the project, I have checked that MIME type for ".XAP" is set to "application/x-silverlight" (in case I'm running from real web server and not from ASP.NET Development Server) , I've even cleared the browser's cache...

After checking AppManifest.xml in XAP file I've identified the problem.

The think was missed... ... ... application startup object in project properties!

It was still pointing to "Old Namespace".App!

image

And thus, AppManifest.xml in XAP file was generated like follows (with EntryPointType pointing to non-existent place):

   1: <Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   2:             EntryPointAssembly="NamespaceChange" EntryPointType="NamespaceChange.App" RuntimeVersion="2.0.30523.4">
   3:   <Deployment.Parts>
   4:     <AssemblyPart x:Name="NamespaceChange" Source="NamespaceChange.dll" />
   5:   </Deployment.Parts>
   6: </Deployment>

The only thing needed to be done is to change Startup object in Visual Studio Project Properties and recompile.

image

Now the manifest generated as it should be and the application works!

So, next time when you changing the namespace don't forget to change the startup object.

 

Enjoy,

Alex

Silverlight & Streaming Media

Lately I'm getting a lot of questions what could be done with Silverlight in in terms of work with streaming media.

Today I'll show what could be done. I've built very simple media player based on MediaElement object and prepared some stream to use in my application. The major focus of this post it to briefly show what could be done with stream in Silverlight and not how specifically do it. I'll be glad to answer any specific questions there will be any.

First about the stream. I've tried to find on my laptop some media, which will be longer than a minute and will also compatible with Expression Encoder 2 formats. After some time I've found an 80's music clip performed by Italian singer Sabrina. This music clip was processed in Expression Encoder 2 - I've added some markers and script command to the stream and encoded it.

image image

Basically, I've defined 4 types of markers/scripts: caption, poll, ADV (advertising) and NAME (general marker).

Now the application itself:

 

The application has very simple UI, and basic media player abilities. Thus, it is still able to stop/play/pause media stream, change volume and displays current position in stream.

The main thing this application does is processing the markers being received from stream. Each type of markers has it own logic. Depending on marker type I'm populating corresponding XAML object:

   1: private void media_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
   2: {
   3:     //Add current marker to collection, which have ListBox bounded on.
   4:     Markers.Add(new MarkerData() { MarkerTime = e.Marker.Time.ToString(), MarkerType = e.Marker.Type.ToString(), MarkerText = e.Marker.Text.ToString() });
   5:  
   6:     switch (e.Marker.Type.ToString().ToLower())
   7:     {
   8:         case "caption":
   9:             txtCaptions.Text = e.Marker.Text.ToString();
  10:             txtCaptions.Visibility = Visibility.Visible;
  11:             double captionsPos = (mediaBox.Width - txtCaptions.ActualWidth) / 2;
  12:             txtCaptions.SetValue(Canvas.LeftProperty, captionsPos);
  13:             captionsTimer.Start();
  14:             break;
  15:  
  16:         case "name":
  17:             txtHint.Text = e.Marker.Text.ToString();
  18:             lastHint = e.Marker.Text.ToString();
  19:             ShowHint.Begin();
  20:             hintTimer.Start();
  21:             break;
  22:  
  23:         case "adv":
  24:             txtADV.Text = e.Marker.Text.ToString();
  25:             ShowADV.Begin();
  26:             advTimer.Start();
  27:             break;
  28:  
  29:         case "poll":
  30:             createPoll(e.Marker.Text.ToString());
  31:             pollTimer.Start();
  32:             break;
  33:     }
  34: }

Each received marker being added to MarkersHistory ObservableCollection, which have ListBox bounded to it. The binding are pretty simple, and I'm skipping it here...

The application generating the polls from poll string - adding dynamic XAML objects to pre-defined pool container, and subscribes to event which gives us a way to know how user reacted:

   1: private void createPoll(string poll)
   2: {
   3:     //Clear poll container from previous poll items
   4:     pollStack.Children.Clear();
   5:  
   6:     //Load poll XML which received from stream
   7:     System.Xml.XmlReader reader = System.Xml.XmlReader.Create(new StringReader(poll));
   8:  
   9:     XDocument document = XDocument.Load(reader);
  10:  
  11:     IEnumerable<XElement> childList = from el in document.Elements()
  12:                                       select el;
  13:  
  14:     //For each question in poll, generates known element
  15:     foreach (XElement e in childList)
  16:     {
  17:         XName att = XName.Get("type");
  18:         switch (e.Attribute(att).Value )
  19:         {
  20:             case "Checkbox": //Yes, yes! I know here is written CheckBox and I'm generating RadioButton... This was just a typo in I had no time to re-encode the media
  21:                 
  22:                 XName val = XName.Get("Value");
  23:                 IEnumerable<XElement> optionValues = from el in e.Descendants(val)
  24:                                                      select el;
  25:  
  26:                 foreach (XElement value in optionValues)
  27:                 {
  28:                     //In this sample I'm generating only RadioButton
  29:                     RadioButton option = new RadioButton();
  30:                     option.SetValue(RadioButton.NameProperty, "CB_" + pollStack.Children.Count);
  31:                     option.Content = value.Value;
  32:                     option.Margin = new Thickness(3);
  33:                     //Subscribing to event
  34:                     option.Click +=new RoutedEventHandler(option_Click);
  35:                     pollStack.Children.Add(option);
  36:                 }
  37:                 break;
  38:         }
  39:     }
  40:  
  41:     ShowPoll.Begin();
  42: }

Application XAML (along with full sources) are pretty simple and could been downloaded from here.

All animations done with simple storyboards for simplicity. There is 2 types of storyboards: "Show*" and "Hide*" - one for showing corresponding object, and one to hide it. "Show" Sotryboards being started at the time of corresponded object population, and "Hide" storyboard by timers, which defined how long specific type of object will stay visible.

Lunch the application on page, try it, and hope you will understand better what could be done with streams in Silverlight application.

As usual, will be glad to answer any question.

 

Full sources (including the music video) are here.

 

Enjoy,

Alex

Silverlight application performance - refresh rate & CPU usage

You just wrote great Silverlight application? How about CPU usage? Do you have pretty static application UI and it still consumes 25-30% of your CPU? Probably you have to control how fast Silverlight should redraw the UI.

To do it, you need to specify MaxFrameRate property in object initialization, like follows:

   1: <asp:Silverlight ID="Xaml1" runat="server" 
   2:     Source="~/ClientBin/ShowFPS.xap" 
   3:     MinimumVersion="2.0.30523" 
   4:     Width="100%" Height="100%"             
   5:     MaxFrameRate="30" 
   6: />

Default value is 60fps, which is pretty high and will made animations looks very smooth. But if you application doesn't have much animations, or your UI is not changing much? Why not limit it to some acceptable value? Even if you application play video stream the MaxFrameRate shouldn't be much faster, than encoded stream rate. NTSC video encoded at 29.92fps, average on-demand video streams encoded at 15fps - why not limit your application at 30fps? To demonstrate the difference I've wrote sample application, with VERY dynamic UI: it has bouncing ball (which is actually canvas with many path objects inside) animation and video (Vista's sample "Butterfly.wmv" encoded at 29fps) played at a background. I'm also have some storyboard running which actually enables me to move ball canvas and calculate/update framerate.

Here is unrestricted framerate screenshot:

60fps

59-60fps according to calculations, 25-30% CPU.

Here is the same application with MaxFrameRate applied:

30fps

29-30fps(exactly like we wanted), 12-15% CPU load. Video is very smooth, animation is also smooth, bit plays slower.

Here is same application at 15fps:

15fps

14-15fps(exactly like we wanted), 6-10% CPU load. Video is still pretty smooth, but "jumps" sometime. For local played file it could be visible, but for network stream it is pretty acceptable.

So, next time when writing Silverlight application, consider specifying MaxFrameRate to ease on CPU.

 

Another nice feature of Silverlight plugin - show actual/desired framerate. To enable it add EnableFrameRateCounter="true" in object definition:

   1: <asp:Silverlight ID="Xaml1" runat="server" 
   2:     Source="~/ClientBin/ShowFPS.xap" 
   3:     MinimumVersion="2.0.30523" 
   4:     Width="100%" Height="100%" 
   5:     EnableFrameRateCounter="true"            
   6:     MaxFrameRate="30" 
   7: />

(*) This will work only in IE.

 

Here is couple more of performance tips:

1. IsWindowless ="false" is faster. Unless you application requires overlay of HTML content on top of Silverlight, don't turn it on.

2. Use solid/opaque background for Silverlight HTML object - it is faster.

3. Try to avoid usage of transparent/semi-transparent colors for XAML controls.

4. Use Visibility="Collapsed" instead of Opacity=0 to hide XAML control.

 

That's it for now.

 

Implementation of Silverlight FPS counter and/or application sources could be found here.

 

Enjoy,

Alex

Silverlight Tip: How to reflect ScriptObject content in runtime

Today I want to show how Silverlight application could "understand" which objects form HTML DOM from hosting page it deals with. The minute before I start, let me show why many of Silverlight developers need it.

Lets assume we have some simple HTML/ASPX page, with some JavaScript functionality and JavaScript objects, like follows:

   1: <html xmlns="http://www.w3.org/1999/xhtml" style="height:100%;">
   2: <head runat="server">
   3:     <title>Test Page For ScriptReflector</title>
   4:         
   5: <SCRIPT language="JavaScript">
   1:  
   2:     //Some JS variables...
   3:     var BOARD   = {};
   4:     var elmBoard;
   5:     var b = BOARD;
   6:     
   7:     //JS Function, which will intialize JS variables, but also will call SL functionality
   8:     function foo()
   9:     {
  10:         elmBoard = document.getElementById("Xaml1");
  11:     
  12:         b.TestPropery = "Alexg@sela.co.il";
  13:         b.extObj  = elmBoard;
  14:         b.extDoc  = b.extObj.document;
  15:         b.extBody = b.extDoc.body;
  16:         b.extWin  = b.extDoc.parentWindow;
  17:         
  18:         //Execute SL functionality
  19:         var sl = document.getElementById("Xaml1").content;
  20:         sl.SL.DoSomething(b);
  21:         
  22:     } 
  23:     
</SCRIPT>
   6:     <style type="text/css">
   7:         #Text1
   8:         {
   9:             width: 300px;
  10:         }
  11:     </style>
  12: </head>
  13: <body style="height:100%;margin:0;">
  14:     <form id="form1" runat="server" style="height:100%;">
  15:         <input id="Text1" type="text" value="Some HTML text is here..."/><input id="Button1" type="button" value="Click Me!" onclick="foo();" />
  16:         <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
  17:         <div  style="height:80%;">
  18:             <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/ScriptReflector.xap" MinimumVersion="2.0.30523" Width="100%" Height="100%" />
  19:         </div>
  20:     </form>
  21: </body>
  22: </html>

image

When user clicks on the button, it does something with JavaScript objects, and then executes some Silverlight function (Silverlight class was already marked as [ScriptableType] and corresponding function was marked as [ScriptableMember]). Assuming we trying to debug Silverlight application and inspect the received object, what we will see?

image

Not very informative...

But what if we need to know what is in this ScriptObject? Which properties it has? Which functions? Could it be done?

Sure it could be done... Lets start by adding two simple functions to our JavaScript section:

   1: //ScriptReflector Helper function - for Properties Reflection  
   2: ReflectProperties = function(obj)
   3: {
   4:     var props = new Array();
   5:     
   6:     for (var s in obj)
   7:     {
   8:         if (typeof(obj[s]) != "function")
   9:         {
  10:             props[props.length] = s;
  11:         }
  12:     }
  13:     
  14:     return props;
  15: }
  16:  
  17: //ScriptReflector Helper function - for Functions Reflection
  18: ReflectMethods = function(obj)
  19: {
  20:     var methods = new Array();
  21:     
  22:     for (var s in obj)
  23:     {
  24:         if (typeof(obj[s]) == "function")
  25:         {
  26:             methods[methods.length] = s;
  27:         }
  28:     }
  29:     
  30:     return methods;    
  31: }

Those functions will help us to "reflect" JavaScript properties at runtime, and they also could be executed from managed code.

Now lets have two managed code functions, which will execute those JavaScript helper functions:

   1: //Properties reflector
   2: public static T ReflectProperties<T>(ScriptObject obj)
   3: {
   4:     T retVal = default(T);
   5:  
   6:     ScriptObject properties = HtmlPage.Window.Invoke("ReflectProperties", obj) as ScriptObject;
   7:     if (null != properties)
   8:         if (int.Parse(properties.GetProperty("length").ToString()) > 0)
   9:             retVal = properties.ConvertTo<T>();
  10:  
  11:     return retVal;
  12: }
  13:  
  14: //Methods reflector
  15: public static T ReflectMethods<T>(ScriptObject obj)
  16: {
  17:     T retVal = default(T);
  18:  
  19:     ScriptObject methods = HtmlPage.Window.Invoke("ReflectMethods", obj) as ScriptObject;
  20:     if (null != methods)
  21:         if (int.Parse(methods.GetProperty("length").ToString()) > 0)
  22:             retVal = methods.ConvertTo<T>();
  23:  
  24:     return retVal;
  25: }

We almost done. I've added function, which will use one of those functions and will return Dictionary<string, object>:

   1: //Deep reflection for ScriptObject proprties
   2: //recursionDepth & maxRecursionDepth are two int variables to control recursion depth 
   3: //in case we will want to get complex properties of JavaScript object
   4: public static Dictionary<string, object> DeepReflectProperties(ScriptObject obj)
   5: {
   6:     Dictionary<string, object> retVal = new Dictionary<string, object>();
   7:  
   8:     string[] props = ReflectProperties<string[]>(obj);
   9:  
  10:     if (null != props)
  11:     {
  12:         foreach (string prop in props)
  13:         {
  14:             if (obj.GetProperty(prop) is ScriptObject)
  15:             {
  16:                 if (recursionDepth < maxRecursionDepth)
  17:                 {
  18:                     recursionDepth++;
  19:                     retVal.Add(prop, DeepReflectProperties(obj.GetProperty(prop) as ScriptObject));
  20:                     recursionDepth--;
  21:                 }
  22:             }
  23:             else
  24:                 retVal.Add(prop, obj.GetProperty(prop));
  25:         }
  26:     }
  27:  
  28:     if (retVal.Count == 0)
  29:         retVal = null;
  30:  
  31:     return retVal;
  32: }

All left to do is to execute those functions. To do it, I've built simple Silverlight Page, with TextBox for input HTML object element IDs, and button to start reflection of the HTML element properties. In my case I've bounded result of DeepReflectProperties function to some ListBox, and ReflectMethods to some TextBox value.

Here is result for  "Button1" (see topmost HTML block):

image

"+"/"-" buttons controls the recursion level.

Execution of HTML Button with "b" JavaScript object (see topmost HTML block) gives following output:

image

image

We done - got properties and method of JavaScript objects in runtime. Now we could use this information to communicate with hosting HTML page more efficient.

 

Full sources here

 

Enjoy,

Alex

Silverlight TreeView Control

I've created new Silverlight Control - this time it is TreeView control.

SilverlightTree.jpg

This time TeeView Templatable & Stylable, supports TreeNodes Drag and Drop. Still not support DataBinding.

All binaries, sources and samples at Codeplex.

Comments/suggestions is welcome.

 

Enjoy,

Alex

Quick Silverlight Tip: Communicating between two Silverlight objects on a single page

Today I'll show how two Silverlight objects (Silverlight applications) could communicate while been hosted on one page.

Earlier today I've seen some blog post by Joel Neubeck about Silverlight objects communication. The way Joel does it is pretty traditional, by providing some JavaScript functionality on host page to communicate with each Silverlight application.

I'll show slightly different approach: each Silverlight application will communicate directly with another (giving the fact, that the IDs of Silverlight applications on page could be provided to each application with initialization parameters. More info about initialization parameters for Silverlight application could be found here).

For simplicity lets assume we two Silverlight applications which are pretty the same:

image  and  image

The only difference in XAML is StackPanel's "Background" color.

Note: The Silverlight application could be totally different, I present here two simple application just as example of something what could be done.

Now lets see the code. First and Second applications differs only by the name it registers itself on page.:

[ScriptableType]
public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();

        //First application
        HtmlPage.RegisterScriptableObject("Xaml1", this); 

        //Second application
        //HtmlPage.RegisterScriptableObject("Xaml2", this); 
    }

    [ScriptableMember]
    public void ExecuteCall(string msg)
    {
        output.Text = msg;
    }

    private void btn_Click(object sender, RoutedEventArgs e)
    {
        //Logic which will update another application with data inputed in TextBox
    }
}

Now the interesting part - onClick event I'll get the instance of another applications object by its ID on page, and just execute its [ScriptableMember] function:

//First application
ScriptObject anotherSL = HtmlPage.Document.GetElementById("Xaml2") as ScriptObject;
//Second application
//ScriptObject anotherSL = HtmlPage.Document.GetElementById("Xaml1") as ScriptObject;


if (null != anotherSL)
{
    //First application
    ((anotherSL.GetProperty("content") as ScriptObject).GetProperty("Xaml2") as ScriptObject).Invoke("ExecuteCall", new string[] { input.Text.ToString() });
    //Second application
    //((anotherSL.GetProperty("content") as ScriptObject).GetProperty("Xaml1") as ScriptObject).Invoke("ExecuteCall", new string[] { input.Text.ToString() });

    input.Text = "";
}

The only difference here is also the name (string) of another Silverlight application, and probably the name (string) of function which we want to invoke.

We done: two Silverlight applications "talks" with each other without JavaScript code written

image

 

Sources here.

 

Enjoy,

Alex

My Presentation at IDF Developers Forum

I will present at next IDF developers forum, which will take a place in Tel-Aviv, 27/07/2008.

If you are an IDF developer, interested in Silverlight and/or want to get some practical tips & tricks about .NET reflection you more than welcome.

Forum Invitation

 

See you there,

Alex