Tuesday, 12 March 2013

Silverlight - Passing javascript objects into a web page dialog arguments

I asked this question on Stack Overflow a while back and was a little surprised that it earned me the tumbleweed award. Has nobody seriously ever done this? Here's the original question: silverlight-passing-an-array-to-a-web-pages-dialog-arguments. It's a scenario quite a few Microsoft Dynamics CRM developers might come across if trying to invoke MSCRM web dialogs from silverlight. But for the purpose of this post I'll keep it somewhat generic.

Take this scenario, you have a web page dialog that requires some dialog arguments to work correctly. And it performs the following when loaded up:

var args = getDialogArguments();
if (args == null) return;
if (args.items == null) return;
var items = args.items;

var len = items.length;
for (var i = 0; i < len; i++)
  var item = items[i];
  cur.id = item.getAttribute("oid");
  cur.type = item.getAttribute("otype");
  cur.values = item.values;
  ... etc

We want to invoke this page via Silverlight, but the question is how do we pass in the arguments correctly? If we take a closer look at the dialog arguments (args) we can see that it has a member called "items" which is an array. Each of these items have attributes called "oid" and "otype". So let me explain what you need to do to set this up.

Before I continue, I want to add a "rule" before I explain how to achieve this. We need to do this without using "dynamic" because this causes you to have to reference the Microsoft.CSharp library which in turn causes your XAP file to bloat.

To start let's ask a slightly different question, what do these objects materialise themselves as within Silverlight? This I already knew the answer to, they are of type ScriptObject which is located in System.Windows.Browser. So why can't we just go and create one of these? Here is where I hit my first roadblock, it has an internal constructor. But, a quick search across the internet reveals that we can set this up using the following:

var dialogArgs = HtmlPage.Window.CreateInstance("Object");

And how about a property on this field?

dialogArgs.SetProperty("items", items);

Excellent, so now we're getting somewhere. Next up, how do you set up this array called "items"? Same way, but we can add indexers to it. Some code for setting up an array and an item will look something like this (I have just created a new GUID for the purpose of this example):

var item = HtmlPage.Window.CreateInstance("Object");
item.SetProperty("oid", Guid.NewGuid());
item.SetProperty("otype", "account");
var items = HtmlPage.Window.CreateInstance("Object");
items.SetProperty(0, item);

And finally, just pass that object straight into your dialog window like this:

var so = (ScriptObject)HtmlPage.Window.Invoke("showModalDialog", lookUpWindow, dialogArgs, "dialogWidth:600px;dialogHeight:600px;");

Job done.

No comments:

Post a Comment