Recently, I have found myself developing a lot of Silverlight customizations for CRM 2011. If you happen to find yourself in the realm of Silverlight and CRM you will more than likely have the need to interact with the CRM form in context. The tool that Silverlight provides for interacting with the hosting web page is the HTML Bridge. The types and methods exposed by the HTML Bridge allow access to the hosting pages DOM and JavaScript objects. By utilizing the types and methods of the HTML Bridge it is possible to access the Xrm JavaScript object of the CRM SDK to set field values so let’s take a look at how the HTML Bridge can be leverages to do so.

There are a couple of different methods that can be used when accessing the Xrm object of CRM. One is to create an object model around the Xrm object that mirrors the Xrm object in JavaScript and the other is to use a dynamic object in Silverlight. I am going to use a dynamic object in this instance as it requires much less code, however, the downside is that there is not any compile-time type checking and errors may not be discovered until runtime.

   1: // Get a reference to the Xrm object
   2: dynamic Xrm = HtmlPage.Window.GetProperty("Xrm");
   3:  
   4: // Set a string field value
   5: Xrm.Page.getAttribute("cei_stringfield").setValue("Hello World!");
   6:  
   7: // Set a floating point field value
   8: Xrm.Page.getAttribute("cei_floatfield").setValue(3.14159);

Notice in the previous example I simply use the HtmlPage.Window object to get a reference to the Xrm property on the hosting page. Also, notice that the local Xrm object is declared as a dynamic variable. Declaring the local Xrm object as a dynamic object allows the object to bypass static type checking. At this point, it is simply a matter of using the Xrm object just as if it were being used from JavaScript. In line 5 of the previous code snippet I have done just that. A reference to the cei_stringfield attribute is obtained and the value is set to a “Hello World!”. In line 8, the same approach is used to set a numeric field.

After seeing how the previous snippet of code works, you may think, as I did, that setting a lookup field’s value could be done using the same technique with an anonymous array object that mimics a lookup fields value as the argument to the setValue function. However, calling the setValue function for a lookup field will not work from within Silverlight due to the way the HTML Bridge marshals managed objects to JavaScript. Fortunately, there is another method that can be used, although it is not quite as elegant. The following snippet shows how a lookup field can be set from within Silverlight.

   1: private void SilverlightSetLookupValue(string fieldName, Guid? id, string entityLogicalName, string name)
   2: {
   3:     // Define eval statements for setting lookup to a value and null
   4:     string setLookupJscript = @"Xrm.Page.getAttribute(""{0}"").setValue([ {{ id: ""{1:B}"", typename: ""{2}"", name: ""{3}"" }}])";
   5:     string setLookupToNullJscript = @"Xrm.Page.getAttribute(""{0}"").setValue(null)";
   6:     string evalStatement = null;
   7:  
   8:     // Set the statement to be evaluated based upon the value of the id argument
   9:     if (id.GetValueOrDefault().Equals(Guid.Empty))
  10:     {
  11:         // Setting the lookup to null
  12:         evalStatement = string.Format(setLookupToNullJscript, fieldName);
  13:     }
  14:     else
  15:     {
  16:         // Setting the lookup to a value
  17:         evalStatement = string.Format(setLookupJscript, fieldName, id, entityLogicalName, name);
  18:     }
  19:  
  20:     // Set the lookup
  21:     HtmlPage.Window.Eval(evalStatement);
  22: }

That’s right, I broke out the big dog, the EVIL EVAL function. As I said previously, it is not the most elegant solution, however, sometimes the heavy hitters like the eval function need to be dusted off and it works beautifully. As you can see, the method in the snippet builds the JavaScript necessary to set a lookup field dynamically as a string and then evaluates the string on the hosting page using the HtmlPage.Window.Eval method within Silverlight.