Lazycoder

3May/071

Confirmed: Silverlight XAML can’t use “namespaced” JS handlers

This thread at the Silverlight forums confirms what I found while playing around with Silverlight 1.0 Beta.

If you are using "Namespaces" to segregate your Javascript code in your Silverlight application, you can't use the nested methods as handlers in your XAML page.

JAVASCRIPT:
  1. player = {
  2.     stop : "",
  3.     play :""
  4. }
  5.  
  6. player.stop = function(sender,args) {
  7.     sender.findName("media").stop();
  8. }
  9.  
  10. player.play = function(sender,args) {
  11.     sender.findName("media").play();
  12. }

XAML snippet

XML:
  1. <mediaElement x:Name="media" ... />
  2. <canvas MouseLeftButtonDown="player.stop" ... />
  3. <canvas MouseLeftButtonDown = "player.play" ... />

If you assign the event handlers in your XAML markup, the code won't fire when the XAML element is clicked. You can move the event handlers up to the Javascript global object and then either handle your events from there or call your namespaced event handlers.

JAVASCRIPT:
  1. function play(sender, args) { sender.findName("media").play(); }
  2. //or
  3. function media_play(sender,args) { player.play(sender,args); }

The third option is to write up the event handlers programatically. I haven't had any luck doing it this way yet. The best place to do this would be in the control onLoad event, which fires before the page onLoad event. The example template supplied in the 1.0 beta SDK uses this method.

JAVASCRIPT:
  1. //example snippet
  2. handleLoad: function(control, userContext, rootElement)
  3.     {
  4.         this.control = control;
  5.        
  6.         // Sample button event hookup: Find the button and then attach event handlers
  7.         this.button = rootElement.children.getItem(0)
  8.        
  9.         this.button.addEventListener("MouseEnter", Sys.Silverlight.createDelegate(this, this.handleMouseEnter));
  10.         this.button.addEventListener("MouseLeftButtonDown", Sys.Silverlight.createDelegate(this, this.handleMouseDown));
  11.         this.button.addEventListener("MouseLeftButtonUp", Sys.Silverlight.createDelegate(this, this.handleMouseUp));
  12.         this.button.addEventListener("MouseLeave", Sys.Silverlight.createDelegate(this, this.handleMouseLeave));
  13.     },

The MS PM said in the forum that this behavior is by design and won't change for version 1.0.

edit: You can't add the namespaced event handlers programatically either. I guess we'll just have to make sure we have unique names for all our Silverlight event handler methods in the global object. :|

FWIW you don't have to use the createDelegate method used above, you can use the "addEventListener" method like so:

JAVASCRIPT:
  1. var stopButton = sender.findName("stopButton");
  2.    
  3.     stopButton.addEventlistener("MouseLeftButtonDown", "media_stop");