Thursday, June 16, 2011

Exposing Silverlight functions to Javascript

Sometimes we need to interact between our Silverlight application and our host page. In this beginners post, I'll describe how to do it along with a mapping example. The target is to choose a state in the host page (which filled from a silverlight function) and then zoom and highlight the state on the Silverlight map.
First we create a class and give it the ScriptableMember attribute. This enables the hosting page to gain access to the class.  The function fill_states will read the the fifty states from the server and run the JS addToStates to add them all to the list in the hosting page. Calling JS from silverlight is easy with HtmlPage.Window.Invoke function.

public class MyScriptableManagedType
{
        [ScriptableMember()]
        public void fill_states()
        {
            QueryTask pQueryTask = new QueryTask("http://sampleserver..../ESRI_Census_USA/MapServer/5");
            pQueryTask.ExecuteCompleted += fill_states_ExecuteCompleted;
            Query pQuery = new Query();
            pQuery.OutFields.AddRange(new string[] { "STATE_NAME" });
            pQuery.ReturnGeometry = false;
            pQueryTask.ExecuteAsync(pQuery);
        }
        private void fill_states_ExecuteCompleted(object sender, QueryEventArgs e)
        {
            IOrderedEnumerable<Graphic> pSorted = null;
            pSorted = e.FeatureSet.Features.OrderBy(g => g.Attributes["STATE_NAME"]);
            
            foreach (Graphic graphic in pSorted)
            {
                string pStateName = graphic.Attributes["STATE_NAME"].ToString().Trim();
                object o = HtmlPage.Window.Invoke("addToStates", pStateName);
            }
        }

The next function is goto_state : gets the state name from JS and then zoom and highlight it on the map.

[ScriptableMember()]
    public void goto_state(string sStateName)
    {
            QueryTask pQueryTask = new QueryTask("http://sampleserver.../ESRI_Census_USA/MapServer/5");
            pQueryTask.ExecuteCompleted += goto_state_ExecuteCompleted;
            Query pQuery = new Query();
            pQuery.ReturnGeometry = true;
            pQuery.Where = "STATE_NAME = '" + sStateName + "'";
            pQueryTask.ExecuteAsync(pQuery);
        }

Read more: Oren Gal