In order to demo Silverlight I created a big lump of XAML that allows me to show most of the core capabilities and play around with things like transforms, brushes, storyboards and the like. It's just an easy way to be able to show some of the capabilities of Silverlight. One problem I faced was that the end result was a bit cluttered - we tend to demo at 1024x768 resolution and that doesn't give you much screen real estate to play with. So I thought I'd organise things in a tab control.
Those capabilities live in the System.Windows.Broswer namespace which has classes such as HtmlPage, HtmlDocument and HtmlElement. A line of C# code such as:
private HtmlElement TabHolder = HtmlPage.Document.GetElementByID("TabHolder");
allows me to grab hold of my "TabHolder" element (you're going to want to see the HTML now aren't you?):
And I can then access the HtmlElement.Children collection of my TabHolder element to access the <li> elements. I give each of these an ID and hook up an event handler to it (all in C#). A bit like this:
private void InitialiseTabs()
int j = 0;
foreach (HtmlElement li in TabHolder.Children)
li.ID = "Canvas_" + j++.ToString();
li.AttachEvent("onclick", new EventHandler(this.HandleTabChange));
This is very cool. I'm now writing all my Silverlight application in C# and it still allows me to access the browser DOM and maniplate elements, respond to events etc. I like this!
Imagine my surprise then when I fired up my application in FireFox and instead of looking like this:
Instead it looked like this:
and all the tab functionality was broken.
I fired up the debugger and 100% failed to get any breakpoints to hit in FireFox. For the record this was 100% my own fault. Anyway, it's pretty easy to get this working:
- Set a breakpoint in your managed code
- Fire up the application in FireFox (easiest thing I find to do is right-click on the page you want and select "Browse with..." then select FireFox
- In VS, select "Debug -> Attach to Process"
- Make sure the "Attach To" code type is set to automatic
- Attach to the relevant FireFox instance
- As my breakpoint was in the Load handler, I had to reload the page in FireFox. This is where my problems started because for whatever reason, F5 wasn't reloading the page so my breakpoints weren't being hit. But not to worry, that's sorted out now.. 🙂
TabHolder.Children.Count was 6 in IE (and hence worked) but 13 in FireFox (this broke various things including using the tab number as an index into the Children collection). What's happening is that FireFox treats whitespace in the source HTML as an element so you get extra text elements in the DOM if you format your HTML source the way I have.
One option is to reformat your source (not elegant). I preferred to add a check in my foreach to ensure the HtmlElement was a <li> before setting the ID and attaching the event handler. Trouble is I couldn't find a good way to do this. In the end I used the Children.Count property as my <li> elements have an <a> child. If you try to use the TagName property, an exception will be thrown for the text elements.
Having sorted that out, it all works a treat. You can even take a look at it if you're interested. As part of the demo I change various properties of the elements such as transforms, brushes etc so you can see the full range of effects but you get the general idea.