attaching to events in a Shape Description

Developer
Jul 10, 2008 at 8:41 AM

If I add a hyperlink in a shape description, can I invoke manage code from it?

For example:

pin.Description = "bla bla bla <br/><a id='pin1'>Zoom to street level</a>";

What is the best way to handle that click?  Do I need to create a javascript function in the host page or can I attach the event in managed code using HtmlPage.Document.GetElementById('pin1').AttachEvent(...

I tried both but in the Javascript function I wasn't sure how to get a ref to the VEMap, and the GetElementById failed, because I guess I accessed it too early?

Anyway any help would be appreciated....

Cheers

Ian

Coordinator
Jul 16, 2008 at 3:13 PM


IanBlackburn wrote:

If I add a hyperlink in a shape description, can I invoke manage code from it?

For example:

pin.Description = "bla bla bla <br/><a id='pin1'>Zoom to street level</a>";

What is the best way to handle that click?  Do I need to create a javascript function in the host page or can I attach the event in managed code using HtmlPage.Document.GetElementById('pin1').AttachEvent(...

I tried both but in the Javascript function I wasn't sure how to get a ref to the VEMap, and the GetElementById failed, because I guess I accessed it too early?

Anyway any help would be appreciated....

Cheers

Ian



The included sample shows how to handle a pin click event. As far as putting a hyperlink in the description and handling that in Silverlight, I'm not sure how you'd do it. You'd probably have to make the link trigger a JavaScript event and have that event call back into one of your Silverlight objects. Or if you name the link and can get to it by it's element ID you can do as you showed above. But there's no 'automatic' way to make that happen.
Jul 16, 2008 at 5:09 PM
This could help with the hyperlink issue:
http://www.silverlightshow.net/items/Silverlight-LinkLabel-control.aspx

Coordinator
Jul 16, 2008 at 11:30 PM
Yes, that linklable control could work if you wanted to to embed it in a Silverlight popup that gets shown when the pin is clicked. The included sample shows how to do a Silverlight popup, so this is feasable. However, if you want to use the built-in Virtual Earth pin popup then you'll have to roll a more manual solution like discussed above.

P.S. the fully supported managed control the Virtual Earth team plans to eventually release will make this much easier.
Developer
Jul 24, 2008 at 3:20 PM

I have been playing with something along the lines of a ShapeCommand class. You could then write something like:

                ShapeCommand command1 = new ShapeCommand() { CommandName = "Zoom", Text = "Zoom In" };
                command1.CommandExecuted += new EventHandler<ShapeCommandCallBackEventArgs>(command1_CommandExecuted);
                command1.CommandArgs.Add(location.Latitude.ToString());
                command1.CommandArgs.Add(location.Longitude.ToString());
                command1.WriteJSMethod();

                ....

                 pin.Description = "bla bla bla<br/>"+ command1.Html;

                ....
Then when the hyperlink is clicked the following would be executed:

                void command1_CommandExecuted(object sender, ShapeCommandCallBackEventArgs e)
                {
                    map.ZoomLevel = 17;
                    map.Center = new VELatLong(double.Parse(e.CommandArgs[0]),double.Parse(e.CommandArgs[1]));
                }

This is far from perfect yet - the args are just strings, and they should be objects, but I couldn't work out how to pass the object array to JS.  Also using the eval as I have below, will mean that there is one function for each pin, which is probably not great(!).  What I was after was a generic way to add commands to the description, without having to touch the hosting page or manually ad some js.

The class is below.  Comments welcome!

using System;
using System.Windows.Browser;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace WordAlbumMap
{
    [ScriptableType]
    public class ShapeCommand
    {
        public string Text { get; set; }
        public string CommandName { get; set; }
        public List<string> CommandArgs { get; set; }
        public event EventHandler<ShapeCommandCallBackEventArgs> CommandExecuted;

        public ShapeCommand()
        {
            HtmlPage.RegisterScriptableObject("ShapeCommands", this);
            CommandArgs = new List<string>();
           
        }

        public string Html
        {
            get
            {
                return "<a href='javascript:" + CommandName + "();'>" + Text + "</a>";
            }
          
        }

        [ScriptableMember]
        public void CallBack(string commandName, string args)
        {
            if (CommandExecuted != null)
            {
                ShapeCommandCallBackEventArgs callbackArgs = new ShapeCommandCallBackEventArgs();
                callbackArgs.CommandName = commandName;
                callbackArgs.CommandArgs = args.Split(';').ToList();
                CommandExecuted(this, callbackArgs);
            }
        }

 

        public void WriteJSMethod()
        {
            StringBuilder jsArgs = new StringBuilder("");
            foreach (string item in CommandArgs)
            {
                jsArgs.Append(item).Append(";");
            }
            jsArgs.Remove(jsArgs.Length - 1, 1);
            HtmlPage.Window.Eval("var args='" + jsArgs.ToString() + "'; var " + CommandName + " = function(){silverlight.content.ShapeCommands.CallBack('" + CommandName + "',args);}");
        }

    }

    public class ShapeCommandCallBackEventArgs : EventArgs
    {

        public string CommandName { get; set; }
        public List<string> CommandArgs { get; set; }
    }
}

Jul 29, 2008 at 6:12 PM
Hi,

I am new to VIEWS. I downloaded the latest source code(13972),compiled and run the code which is working properly.

I wanted to know what events to fire to display the  pop up (silver light application). Currently I am not able to see the pop up on the page.

Thanks in anticipation.

Thanks
Mohammed Idrees
Coordinator
Jul 29, 2008 at 6:47 PM
Mohammed, that's probably a topic for another thread.

Ian, I love the idea. What was the problem with the argumetns going through JavaScript? Is it because you wanted the args to come back through the [Scriptable] callback? I'm not sure you really need the args to roundtrip through the JavaScript layer at all. I think all you need to know is that the callback fired (i.e. the link was clicked). You're callback already happens within the context of your instance, so the parameters can just be stored as class-level variables.

For that matter, I'd actually change your command and EventArgs class to return a Data or Tag property that is of type object. That way the application can associate any data it wants with the command. It can be a simple string or a complex business object. This is a common pattern in .Net and the optioal parameter in BeginInvoke is an example of this.