Note – these posts are put together after a short time with Silverlight 4 as a way of providing pointers to some of the new features that Silverlight 4 has to offer. I’m posting these from the PDC as Silverlight 4 is announced for the first time so please bear that in mind when working through these posts.
With Silverlight 4 comes C# 4 and VB 10 and some of the new capabilities around being able to do dynamic dispatch. As in the full .NET framework that means that you can use new ways to invoke methods/properties/events at runtime via dynamic dispatch into objects either via;
- reflection
- COM interop
- some custom mechanism – i.e. the dynamic support is pluggable
There’s a custom implementation in Silverlight 4 around dynamic invocation into the HTML DOM’s types.
Since version 2, Silverlight has had a very strong story around integration with the HTML DOM and you can do all kinds of interoperability between the Silverlight world and the HTML world including manipulating the UI’s of the 2 worlds from their 2 programming models and also passing arbitrary types backwards and forwards from .NET to Javascript.
However, the code that you end up writing isn’t always “that pretty” in that from the .NET side you’re entering into a loosely typed world. So, if I’ve got a simple HTML page that’s hosting my Silverlight plug-in;
<body> <form id="form1" runat="server" style="height:100%"> <div id="silverlightControlHost"> <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="50%"> <param name="source" value="ClientBin/SilverlightApplication15.xap"/> </object></div> <div width="100%" id="myDiv"> </div> </form> </body>
and I want to write some Silverlight code that runs on a button press in the UI and grabs that DIV and adds an INPUT into it and then handles the click event on that INPUT back in .NET code I can write something like;
HtmlElement div = HtmlPage.Document.GetElementById("myDiv"); HtmlElement button = HtmlPage.Document.CreateElement("input"); button.SetAttribute("type", "button"); button.SetAttribute("value", "click me"); button.AttachEvent("onclick", (object s, HtmlEventArgs e) => { slButton.Content = "Thanks"; }); div.AppendChild(button);
where slButton is the Silverlight button whose handler this code runs in response to.
That’s all “nice” but in Silverlight 4 I can take advantage of the dynamic language support to be a bit neater and not have to keep calling things like SetAttribute as in;
HtmlElement div = HtmlPage.Document.GetElementById("myDiv"); dynamic button = HtmlPage.Document.CreateElement("input"); button.type = "button"; button.value = "click me"; button.onclick += new EventHandler((s, e) => { // TODO - not got this working just yet... slButton.Content = "Thanks!"; }); div.AppendChild(button);
You’ll notice that we can just access button.type and button.value and the underlying dynamic dispatch mechanism will reach into the HTML DOM and do the right thing with respect to dynamically setting the properties to the right values – it makes for easier to read code ( imho ) but it’s still dynamic dispatch so you can hit a bunch of runtime errors on those innocuous looking lines of code 🙂
Note – at the time of writing I’ve yet to get my onclick handler to work if I set it up via this route but I suspect that’s more of a bug I’m hitting than a permanent limitation.