Developing with Silverlight and the ESRI Silverlight/WPF API – Part I

I moved from ESRI to GIS, Inc. early last year, just as the Silverlight API was getting going, and hadn’t had a chance to work with it until recently. I had lots of experience with the .NET ADF but was pretty much new to Silverlight. I’ll share some experiences with Silverlight in this post. I’ll follow up with a second post specifically on the ESRI Silverlight/WPF API.

I had picked up a book on Silverlight 2 some time ago, but actually found the easiest way to get started was with the tutorials at Silverlight.net. Tim Heuer’s series there is a great run-through of the main features in Silverlight. I then looked through some of the lessons in the Learn section, like Jesse Liberty’s videos. With those under my belt, I was able to get started with the ESRI API. I’ve also picked up Matthew MacDonald’s Pro Silverlight 3 in C#, which is a wonderful resource that goes into great depth (it’s not a tutorial format, so best to use it as a resource/reference).

I’ve mostly used Visual Studio 2008 for Silverlight so far. Expression Blend 3 is pretty much essential, though, if you want to do complex styles or animations. Since clients typically are attracted to Silverlight because of its fancy graphics and animation capabilities, that means Blend is a must, even for developers. Silverlight/XAML allow you to completely customize the look and feel (i.e., template) for standard controls like buttons and checkboxes. That sort of thing is painful and slow to do via markup in Visual Studio. Blend is also very useful for setting bindings for data sources (more on binding in a moment). I had heard that Visual Studio 2010 would allow design-view editing like Blend, but my experience so far with the release candidate isn’t promising. VS 2010 RC handled a very simple XAML page, but threw up its hands when I tried to view a more complex (and real-world) page. It also doesn’t seem to have Blend’s capabilities for editing properties, styles, and bindings. It also seems more sluggish than VS 2008.

Some day, I hope Microsoft creates an IDE that combines the capabilities of Blend and Visual Studio. Microsoft plays up transitioning between the two, but it’s fundamentally weird to have to switch back and forth between applications. You need Visual Studio for most any code writing, since Blend has no intellisense and can’t be used for debugging (no stopping at breakpoints, etc.).

One of the best aspects of Silverlight is the layout engine, or in other words, no more HTML/CSS hassles. I’ve torn many hairs out with ASP.NET applications in trying to get an element to go where I wanted it, or to look as I needed it to. Silverlight (actually XAML, the markup language it shares with WPF) allows you to place elements precisely, without the weird quirks of CSS or the vagaries of browser implementations. It took a while to get the hang of XAML layout and styles, like margins, padding, alignment and such, but once you understand the system, you can pretty easily lay out your page as you want. It’s also a snap to get the application to fill the page even when the user resizes the browser – something unnecessarily painful in traditional web pages.

Silverlight also makes it easy to consume Web services. You add a web/service reference in Visual Studio just like for a server-side ASP.NET application, and it builds the proxy for easy use in the application. I should mention though that I’ve had occasions where it fails to create the proxy properly, and I’ve had to generate the proxy manually and include it in the project. That works OK but then you have to refresh the proxy manually when you change the Web service. (I just noticed Ken Smith’s tip on deselecting the “Reuse types in referenced assemblies” option – seems to work on first try with a service that hadn’t worked previously.)

As a Web developer, I have to keep reminding myself that the Silverlight application is, for practical purposes, a desktop application. The action is happening on the user’s machine. No more worries about stateless Web requests—you can create an object and reference it later, without thinking too much about where to store it in the meantime. Of course there are hazards there too, like limitations on what you can access on the user’s computer (not much) and the possibility of creating a slow and memory-hogging application.

Another interesting difference from server-side Web applications is how resources like fonts work. Silverlight natively supports only a handful of fonts like Arial and Times New Roman. It doesn’t use fonts installed on the user’s computer. If you want to use a special font like Goudy Old Style or any ESRI symbol font, it has to be packaged into the .xap file the user downloads from the server. Not only does that quickly enlarge your download, but the end user can easily unzip the .xap file and pull out the fonts you embed (via the free.NET Reflector utility). That means that in most cases you have to get permission from the font owner to redistribute it, and typically pay a fee. I’m not sure what ESRI’s policy is on redistribution of their fonts.

Silverlight development does have some rough edges, such as:

  • No ability to debug bindings. Binding to data and resources is at the core of Silverlight. You don’t typically create data control elements or set properties in code; instead, you bind properties and controls to data objects or other resources. That’s great when it works, but when it doesn’t, it fails silently. You might get a notice in the Output window, but you can’t step through the binding process. It’s often hard to tell if the data are bad, or your markup is faulty, or some other cause. I had a couple of occasions where the bindings actually worked, but I had inadvertently set the control to be invisible or zero width, so it didn’t appear! In ASP.NET you could at least view the source of the output page and see the markup produced, or use a tool like Fiddler2 to examine the page structure and elements. This data binding issue is a headache in Silverlight and leads to reduced productivity, as the developer has to do lots of round-about troubleshooting.
  • No intellisense for XAML markup extensions. These markup extensions allow you to do things like bind the Text property of a TextBlock control to a field in a data source. But in Visual Studio there’s no help writing those statements (Blend does have a UI for some of this). You don’t find out you have errors until maybe at compile time, or even at runtime in some cases (or as mentioned above, the binding can simply fail silently).
  • Unhelpful error messages, especially for markup issues. You’ll see messages like AG_E_PARSER_BAD_TYPE, with no information on which file/page contains the error, and sometimes no line information or stack trace. Hopefully you’ve just made a minor change to the markup so you have an idea where the problem lies, but that’s not always the case when this happens.
  • Difficulty finding elements on the page. If you’re in the same context and know the name, you can reference the control, but if you’re, say, in an included user control, or the element was created programmatically without name, I haven’t found a way to search the entire application by control name or type. There’s the VisualTreeHelper, but that only goes up and down the immediate XAML tree, and doesn’t work everywhere (like in data templates).
  • No automatic mouse wheel scroll in elements with scroll bars. If you add a ScrollViewer or have a ListBox with scroll bars, users can’t scroll content with the wheel, unless you pull in a third-party utility. Seems like a minor issue, but users have gotten very used to that convenience, so it should be built in. Silverlight 4 will expose a MouseWheel event, but you’ll have to handle it programmatically.

Ken Smith shared similar complaints in a couple of posts (here and here). Hopefully Microsoft will improve Silverlight regarding these behind-the-scenes issues over time, though Silverlight 4 doesn’t seem to offer too much improvement.

Despite these issues, I definitely enjoy working with Silverlight. It’s got a lot of advantages over traditional Web development, and plenty of power to create attractive and useful applications.

I’ll follow up with a post on the ESRI Silverlight API shortly.

It Works On My Machine (Application Testing)

(But does it work on yours?)

Being part of a small development shop with 2 developers that is currently growing now with 25 developers, I have experienced frustrations along the way that I continue to learn from. I can’t tell you how many times that I spent the weekend busting my butt to get an application debugged and tied up tightly only to find that my boss can’t get it running the first time he tries it on his machine. My only response, as I think about the family events I missed over the weekend is… “I don’t understand what happened, it worked on my machine.”

Below are two short examples for creating a project. The first example roughly describes how I previously developed and release a project and the second example describes the procedure we use here at GISi today.

 Example 1:  A developer creates a project that is to be delivered to a customer. When the project has been completed, the installer for the application is built in release mode and the developer installs it on the development machine for testing.  After successfully testing the final product on the development machine, it is turned over to someone else for testing before it goes out to the customer.  (Well, let’s hope that is what happens anyway.)

Next, the developer turns the project over to the person that is going to install and test it on their computer.  After installing and testing the project, the tester goes back to the developer and says some portions of the application did not work or they got errors when clicking on a button or when opening or closing a dialog. Or, even worse, the installer failed to install the application. This is when the developer says, I don’t understand, I installed and tested it on my computer and… “It works on my machine!” But the reality is that it wouldn’t work on any other machine.

 Example 2:  A developer develops and debugs a project as the code is written for each button; tool; dialog; etc… to make sure everything is working as it should.  After the project has been completed and all of the bugs have been resolved, the installer for the application is built in release mode for testing.  Before the build is released for testing by others, the developer should test the release build to make sure everything was installed properly and the final product actually works as it did when testing in debug mode.  The developer can install on the development machine to make sure the installer works and has the correct information on the installer dialogs.  Also, the developer can test the product on the development machine to verify the product works as designed after it has been installed.  

However, before turning the project over for testing by others, the developer must install and test on a clean test machine.  One reason to test on a clean test machine is to make sure that all of the required assemblies; databases; registry entries and other required files get installed in the proper locations. Next, the developer should test the project on the clean machine to make sure all of the buttons; tools and dialogs work properly. If the developer follows this procedure before turning it over to someone for testing, he will be assured he won’t have to say well, “It works on my machine!”