UPDATE 2-Oct-08: Deep Zoom Tag Cloud example updated for RC0
A comment on a previous post says Because WebClient has a dependency on a web server running, the version I wrote won't be added as a project template into Deep Zoom Composer, which sounds like a shame and got me wondering how to get around the 'WebClient' problem.
The 'WebClient' problem is actually related to security and the sandbox. Kirupa's Tag Sample needs to load
Metadata.xml
into Silverlight/c#, and it uses WebClient
to trigger an asynchronous download... but you can't do that if you Silverlight control is hosted in a web page off your local disk!
It turned out to be pretty easy to get around - firstly here's a screenshot: the page has simply been double-clicked off the hard-drive, yet it is still able to load *some metadata* to enable tagging & description display.
Ah-ha - so you notice I said "some metadata" and not
Metadata.xml
. Since it is so hard to 'load' Xml off the filesystem (thanks to the Silverlight sandbox), and since my Tag Generator is parsing and re-writing Metadata.xml
anyway, we just write another (JSON) file - Metadata.xml.js
then go around the sandbox and load as JSON via Javascript Interop.It took a little experimenting to get right, but the basic changes to make it work are:
1) Tag Generator emits JSON
2) Tag Generator saves "Metadata.xml.js"
3) Html page references "Metadata.xml.js"
4) Declare 'matching' C#/Silverlight class (to JSON), and a method to Deserialize to it
5) THE MAGIC Javascript
Eval
turns our string into JSON, replacing the LoadXMLData()
at the start of the post6) Update
xmlClient_DownloadStringCompleted
to walk the JSON object array instead of Xml, and the rest of the code 'just works'!You'll want to add a couple of assembly references to your Silverlight (System.Json, System.ServiceModel.Web) and namespaces (System.IO, System.Text, System.Json, System.Runtime.Serializatin.Json) to get everything working. This post on Consum(ing) a JSON object in Silverlight set me on the right track, and the Silverlight and JavaScript Interop Basics filled in the gaps.
The Javascript Interop is capable of much more:
HtmlPage.Window.Invoke
for going to Javascript, and the [Scriptable*]
attributes to expose managed code for Javascript to use; but a simple Eval
was all I need for this little experiment.p.s. I did wonder whether it's possible to "include" an .XML file in the HTML for DOM access... I vaguely remember IE supporting 'XML data islands' or something along those lines. However JSON definitely seems like the 'modern' way to approach the problem IMO, and without getting into x-browser compatibility stuff...