Latest Tweet:
  • Loading...

This blog post is one of three I’m posting to introducing some of the new features in the Silverlight Toolkit announced today at the PDC 2008. For more information about and downloads of the toolkit check out
http://www.codeplex.com/Silverlight.

Auto complete textboxes have become a common interaction model in both web and desktop applications. All the modern browsers have smart suggestions directly in the address bar. E-mail clients on the web and on your desktop will try to suggest the recipient by looking in your address book as you type. Leveraging auto complete in your application is a great way to improve the user experience by limiting errors and cutting down the amount of typing needed to complete a form.

One of the new controls in the Silverlight Toolkit is the AutoCompleteBox control, and in this post I’m going to show how to implement auto completion it in the Dive Log application. The AutoCompleteBox control supports both data bound suggestions as well as custom code to get suggestions asynchronously, for instance by calling a web service. I will cover both scenarios and show how the auto completion code fits in to the Model-View-ViewModel architecture of the Dive Log application.

The AutoCompleteBox control looks and feels like a textbox, and has a Text-property. This makes it easy to upgrade any existing application that uses textboxes to use the AutoCompleteBox control instead. In the Dive Log application I’m going to upgrade the location and buddy textboxes to AutoCompleteBox controls. The auto complete suggestions for dive buddy will be data bound to local values, while the suggestions for dive location will be retrieved from the Dive Log web service.

TextBoxes that needs AutoComplete

Data Bound Auto Complete Suggestions

For safety reasons you never dive alone and always have a buddy with you. There is a good chance you will do multiple dives with the same diver, and having to type in the full name every time you log a new dive can be bothersome. To improve the user experience I’m going to replace the textbox with the AutoCompleteBox control. The suggested values for auto completion are going to be a list of all the buddies the user previously has dived with. If this is the first time with a new buddy the user simply types in the name as in any textbox, and for the next dive this name will be included in the auto complete text box.

The Dive Log application uses the Model-View-ViewModel pattern to keep things nice and separated. All UI components on screen are data bound against properties on the ViewModel. One of the properties is a list of all the logged dives for the currently logged on user. For the AutoCompleteBox control we need to expose a new property returning a list of all dive buddies. This is implemented as a simple LINQ query. The ViewModel implements the INotifyPropertyChanged interface, so every time the list of dives changes we need to fire the event to signal that the list of Buddies has changed.

Property exposed by ViewModel with suggestions.

Now that we have prepared the ViewModel with this new property we can replace the buddy textbox with the AutoCompleteBox control. The AutoCompleteBox control has a Text-property just like the textbox. The name of the buddy for the selected dive is two-way data bound against the Text-property on the AutoCompleteBox control. The AutoCompleteBox has an ItemsSource-property that we bind against the new Buddies-property on the ViewModel.

Buddy TextBox replaced with AutoCompleteBox 

When we run the application and start typing the name of our dive buddy the AutoCompleteBox control will make suggestions based on the values in the data bound list. I haven’t applied any styling to the control, so that the moment the UI looks a little bit off. We will deal with that later.

AutoCompleteBox without styles applied

Auto Complete Suggestions from a web services

In some cases the list of possible matches is too big to be kept in memory and loaded when the application starts. Examples of this could be the Amazons book database or auto completion in an e-mail client where you have a shared address book with thousands of contacts. In these cases you need to query the server for auto complete suggestions as the user types to only get relevant suggestions. For the Dive Log application we’re going to implement code to call a web service to get suggestions for dive locations. There is a good chance that someone else have been to a location before you, so by querying the entire Dive Log database we can provide better auto complete suggestions, and at the same time save bandwidth as we don’t have to download everything at once.

To implement asynchronous suggestions in the AutoCompleteBox control you need to subscribe to the Populating-event of the control. This event will let you run code when the control is trying to populate the list of suggestions. In the event handler you need to set the Cancel-property on the event argument to false before calling your web service to get suggestions. The event argument also contains a Paramter-property holding whatever text the user has typed already. We pass this parameter to the web service to get dive locations that match the text the user have typed in.

AutoCompleteBox Populating Event Handler

I had some problems deciding where to put the code to populate the AutoCompleteBox control. The code needs to have a reference to the AutoCompleteBox control to hook the Populating-event, set the ItemsSource-property and call the PopulateComplete-method when the results are ready. The most obvious place to put this code is directly in the code behind of the page. However, I always try to keep the amount of code in View to an absolute minimum, so my second attempt was to put the code responsible for handling the event and calling the web service in a separate class. The class took the AutoCompleteBox control in the constructor to get a reference to the control. Then in code-behind I would simply instantiate the class and pass in the AutoCompleteBox control to wire things up. This is a better solution than having everything in code-behind, but I’m still not happy. The class responsible for managing auto complete suggestions also needs a reference to the web service client to get suggestions from the server, and to not break testability I want to provide this dependency in the constructor.

The solution I ended up with has a separate class responsible for managing auto complete suggestions, but the reference to the AutoCompleteBox control is set using a property instead of the constructor. In the setter the class will register the event listener for the Populating-event. The class also takes the IDiveServiceClient interface in the constructor so that I can use the Ninject IoC-container to create the object.

AutoCompleteBoxTarget property 

The final problem is how to set the AutoCompleteBox property saying which control the class is providing auto complete suggestions for. I implement an attached dependency property which allows me to use XAML to link the AutoCompleteBox control against the class responsible for managing auto complete suggestions. The implementation of the dependency property I similar to the Command-pattern implementation used in the Dive Log application. I’m not going to include the full implementation here, as the source code is available for download.

AutoCompleteBox AttachedProperty

The web service method returning suggestions is incredibly simple. It takes a prefix argument and runs a simple LINQ query getting all dive locations starting with that prefix.

GetLocations WebService Method

Styling the AutoCompleteBox

Styling the AutoCompleteBox to make it fit with the look and feel of the Dive Log application is really simple. If we use Expression Blend to edit a copy of the default control template we see that the core pieces of the AutoCompleteBox is a TextBox, a Popup and a ListBox. The Popup shows suggestions in the ListBox as the user types in the TextBox. So if you know how to style a TextBox and a ListBox you got the skills needed to style the AutoCompleteBox. I would recommend styling the ListBox independently, as you cannot see the suggestion ListBox in design mode.

Styling the AutoCompleteBox in Blend 2

Since the Dive Log application already have predefined styles for TextBoxes and ListBoxes it didn’t take long to make the AutoCompleteBox look just right. I simply had to apply the excising styles and tweak the border control around the ListBox to make it look nice.

AutoCompleteBox styled

Summary

The AutoCompleteBox control in the Silverlight Toolkit makes it really easy to enhance the user experience by providing auto complete behavior to your application. The control can easily replace excising textboxes where that makes sense. The control gives you the flexibility to use either data bound auto complete suggestions, or write custom code to access web services to get suggestions. The Dive Log application includes examples on how to do both. The Dive Log source code also contains an example of an attached dependency property that allows you to add asynchronous suggestions without cluttering your code-behind.

This blog post is one of three I’m posting to introducing some of the new features in the Silverlight Toolkit announced today at the PDC 2008. For more information about and downloads of the toolkit check out http://www.codeplex.com/Silverlight.

Good layout is a critical to the overall user experience of any application. Silverlight 2 comes with three layout controls; Canvas, Grid and StackPanel. You can also create your own layout controls by deriving from the Panel class. There are already several examples online of community implementations of layout controls. Dave Relyea has implemented an animated wrap panel, and Robby Ingebretsen has created an AnimatingPanelBase that makes it easy to implement animated layout controls.

In the Silverlight Toolkit Microsoft includes two new layout controls; DockPanel and WrapPanel, and one new decorator; the ViewBox. In this blog post I will introduce these controls in a Silverlight context, and give some examples of how to use them.

Make your controls Wrap using the WrapPanel control

The WrapPanel is similar to the StackPanel. In addition to stacking elements on top of each other it wraps them in rows and columns. This is similar to how the Windows Explorer works when you’re viewing a folder and resizing the window. Explorer will wrap any file icon to the next line as the window size decreases. This is layout behavior is useful in many situations, and for this example I’m going to update my YouCard example application to use the WrapPanel.

The YouCard application lets you view your Twitter friends, and each friend gets a card with name, bio and the most current tweet. The current implementation uses a StackPanel inside a ScrollViewer. If you add too many Twitter users you have to scroll horizontally.

This isn’t efficient use of screen real-estate as we have plenty of space above and below the line of cards. This is a good place to introduce the WrapPanel, as we could fit in multiple rows of users depending on the screen resolution. The list of cards is implemented using an ItemsControl that is data bound against a list of Twitter-user objects. The ItemsControl lets you specify an ItemsPanel and an ItemTemplate. The ItemsPanel let you specify which panel that controls the layout of all the child items. The ItemTemplate lets you specify which control to use for each item. When the control is data bound it will create one instance of the stuff inside the items template for each element, and add them to the panel defined in the ItemsPanel. To implement the WrapPanel instead of the StackPanel I simply have to change one line of XAML.

YouCard updated to use WrapPanel

When we run the application the behavior have changes. The WrapPanel will try to position as many cards as possible on screen. When one row is full it will wrap and create a new row. If I change the Orientation to Vertical it will create columns instead of rows. By using the WrapPanel we can fit more cards on screen at the same time without scrolling.

YouCard resizing

Dock your controls to one of the sides using the DockPanel Control

The DockPanel layout control enables docking of controls to any side of the container. The controls added to the DockPanel will take up the entire width or height depending on which side it’s docked to. You control the position of the children control by setting the attached Dock property. The children can be docked to Left, Right, Top and Bottom.

DockPanelCodeExample

In this example I’ve added five buttons, four of them docked to the sides of container. The last one doesn’t have a dock property, and will take up any space left inside the control because of the LastChildFill property (which is true by default). If you set the LastChildFill property to false, the fifth button will be docked to the left which is the default Dock value.

DockPanelExample 

The DockPanel control can be really useful in many situations, for instance when designing the top level layout of the user interface. You can dock your menu and header to the top, a copyright footer to the bottom, and a sidebar to the left or right.

Scalable UI using the Viewbox

The ViewBox isn’t really a layout control; it belongs to a family of controls called decorators. It’s a panel like control but only accepts one child element. The Border and the ScrollViewer are other examples of decorator controls. However, ViewBox can be really useful when dealing with the layout of your application so I think it fits nicely into this blog post.

The ViewBox addresses the challenge of scaling content relative to the available surrounding space. It’s quite a mouthful, but what it really does is make a control take up all the available space, without stretching it. Instead it applies a scaling transform to scale the content to use the available space. In many cases this is exactly the kind of behavior you want, and without the ViewBox you would have to write custom code to achieve that.

The Grid control is great for creating flexible user interfaces that will stretch and grow or shrink as the window size changes. The DockPanel behaves the same way. If we look at the screenshot of the buttons in the Dock panel example the buttons are all stretched to take up any available space. The text inside the buttons does not change size, and instead we end up with allot of empty. By simply wrapping the DockPanel inside a Viewbox the buttons will scale by zooming instead of stretching.

ViewBoxCodeExample

ViewBoxExample

By using the ViewBox to scale your UI you can really take advantage of the fact that all Silverlight 2 controls are based on vector graphics. When the ViewBox scale the buttons the quality doesn’t degenerate like it would if the graphics was bitmap. Instead the buttons remains crisp and comfortable to read.

Summary

The new layout controls in the Silverlight Toolkit adds some great value by adding the WrapPanel, DockPanel and ViewBox to our toolbox. These controls also help make Silverlight 2 more alligned with WPF where these controls are already available. Developers with a WPF background should feel comfortable with these new controls. Silverlight 2 developers who know the Canvas, StackPanel and Grid should definitely start exploring these controls and how they can help layout the user interface. Remember that you can combine and nest these controls however you like. You can have DockPanel laying out the top level UI, and then have some other container control take up the remaining space inside the DockPanel. The DockPanel and WrapPanel are also great examples of how to implement custom layout controls in Silverlight 2. If you have special layout requirements you can use the DockPanel or WrapPanel source code as a starting point for your own layout control. I also recommend checking out Dave Relyea’s two part series on the Silverlight 2 Layout System and Joseph Ghassan thorough walkthrough of Silverlight Layout Management

This blog post is one of three I’m posting to introducing some of the new features in the Silverlight Toolkit announced today at the PDC 2008. For more information about and downloads of the toolkit check out http://www.codeplex.com/Silverlight.

One of the strengths of WPF and Silverlight is the ability to change the style or template of any control. This gives the designer maximum flexibility to change the look and feel of an application, without breaking its behavior. The Silverlight 2 styling support has some major shortcomings, specifically around dynamic and implicit styles. Dynamic styling enables you to change the style of a control at runtime without having to recreate it. Implicit styling means applying styles to all controls based on type, and not a specific style name. Implicit styling is similar to applying CSS styles to a H1-element, instead of having to specify the CSS-class name of the element. The benefit of implicit styling is that you can change the look and feel of all the buttons, textboxes, checkboxes or any other control without having to apply a specific style key to all the elements. The Silverlight Toolkit introduces the ImplicitStyleManager which adds support for implicit styling and themes to Silverlight 2.

There are already quite a few good looking themes for Silverlight 2. Tim Heuer did a blog post earlier this month covering some of the themes available, and specifically the work of Corrina Barber and Dave Crawford comes to mind as great examples. Today these templates are deployed as XAML files, with instructions on which part of the file to copy and paste into your App.xaml file. You also have to apply the styles to every single control in your application, and the name of each style is often different. Dave calls his button style BlackGlossyButton, which is different from Corrina’s naming convention. That means that you have to go over and re-apply the style to all your controls if you want to use Corrina’s theme instead of Dave’s theme.

With the new ImplicitStyleManager designers like Corrina and Dave can style a button without having to give it a specific key. They can share their themes as resource dictionary file, and any developer who wants to use the theme simply includes this file and applies it using the ImplicitStyleManager. This is going to make theming of applications allot easier as you simply include a new XAML file to get a new look and feel of your application. Scott Guthrie has commented on his blog that they will be creating some form of online gallery where designers can share their Silverlight themes.

The way create themes is fairly straight forward. You add a new XAML file to your project and mark it as Content (and not as Page which is the default option). Next you build up your resource dictionary, and for your styles you no longer have to apply a key (unless you want to). You simply set the target type to style a button, textbox or any other control. The theme gets applied to your application by using the ImplicitStyleManager attached properties on any container control. All child elements inside that container will get the theme style applied.

ImplicitStyleManagerSample

For this example I have taken Dave’s glossy control theme and turned it into a Silverlight Toolkit theme. When I run the example code above, this is what my button looks like:

ImplicitStyleManagerHelloWorld

All I had to do to turn Dave’s glossy theme into a Silverlight Toolkit theme was remove the key on each on the style. That way I don’t have to specify the key for my button style, as the theme will be applied implicitly by the ImplicitStyleManager. The next screenshot shows a typical data entry screen using Dave’s theme and the Shiny Blue theme from the Silverlight Toolkit (one of the six included themes).

TwoAppliedThemes

In the above example I didn’t have to change any of the XAML of the application, or name of styles, in order to change the entire look and feel of my application. In the future I’m sure we will be seeing lots of new themes from the community as well as commercial vendors. The ImplicitStyleManager makes it easy to share themes and apply them to your application. There are still some shortcomings to the styling model. Support for dynamic resources is one of them. In order to change the theme while the application is running you have to recreate your UI before applying the theme. This is almost like having to “reboot” your user interface, and is not an optimal user experience. However, having Theme support is still a great way forward and opens up many new possibilities.

SDDN Logo

Earlier this week Australian Silverlight enthusiast Jordan Knight announced the Silverlight Designer and Developer Network initiative. This is a new user group starting up in Melbourne, focusing on the design and development aspects of Silverlight. First meeting is scheduled Thursday November 27 at 5:30 PM for a 6PM start. The venue is Microsoft Theatre, Level 5, Freshwater Place, Southbank. Microsoft User Experience Evangelist Shane Morris will be delivering a key note to kick off the group. I will be giving a presentation covering the current state of the Silverlight union. I will talk about any major Silverlight announcement from the PDC, what have been announced around the future, and some of the interesting community projects around Silverlight 2.

The SDDN is a great initiative for many reasons. Most importantly it creates a meeting forum to bring developers and designers together. Getting designers engaged is a key success factor for Silverlight. I really hope this initiative can help that happen. Secondly the Network-part of the name suggests this is more than user group meetings. The SDDN has ambition to build a strong online presence, with high quality recordings of all meetings. This is a great way to reach out to a wider audience, as well as developers and designers working in smaller/remote areas who might not have access to a user group like this. Big kudos to Jordan for making this effort!

Check out Jordan’s announcement post and the new (but still under construction) site for more details. Hope to see you at the first SDDN meeting!

Meet Me In Los Angeles With the SDDN announcement out of the way the next point on my agenda for this “what’s up” blog post is the PDC. I’m writing this while sitting at the gate waiting for my flight to Los Angeles. I will be attending PDC 2008! I had the pleasure of attending PDC back in 2005, and that was an amazing experience. This year I have high expectations to the PDC as it has been three years since last time. I tried to set up my agenda, and ended up with at least two conflicting sessions for each time slot! There is just so much great content. Thankfully Microsoft is putting a big effort into recording all sessions, so at least that’s a chance to catch up on the sessions I miss out on. I don’t know if the recordings will be made available publicly, but I sure hope so.

I’m looking forward to networking with fellow peers in the Microsoft and Silverlight development community. If you’re attending and want to catch up, drop me an e-mail at jonas@follesoe.no, or ping me on Twitter (@follesoe). See you in LA!

Silverlight 2 - No Longer in Beta! As most of you probably know by now Microsoft released Silverlight 2 with supporting tools earlier this week. I’ve been following the development of Silverlight closely, and it’s great to see it come out of beta. Hopefully this means more people will seriously consider Silverlight 2 for their applications. I also think we’ll see more and more content about frameworks, patterns and practices built on-top of the Silverlight 2 framework. Since Silverlight 2 have so much in common with WPF and .NET there already is lots of great stuff ported over, but I expect allot more to follow.

I have now upgraded my three main sample applications, WebCam, DiveLog and YouCard, to the RTW bits. It didn’t have to change any code, as I did the upgrade to RC0 when it released. The updated samples are available in my Windows Live Sky Drive folder, as well as embedded at the end of this post. I have also updated the release of Colorful Expression to clearly indicate that Expression Blend 2.0 SP1 is fully supported.

I did a talk at the Victoria .NET User Group about Silverlight this Tuesday, and hopefully got some new readers to this blog. I normally don’t do link-blogging so this is an exception. I’ve gone through my blog archive (27 posts tagged Silverlight) and picked some of the posts I’m most happy with and written a short summary.

Posts related to the Dive Log application

  • TechEd 2008 – Silverlight 2 for Developers
    I wrote the Dive Log application as a demo for my Tech Ed 2008 talk. The post introduces the projects, contains link to a video of my Tech Ed talk, as well as other relevant links.
  • Back and forward navigation in Silverlight 2 using ASP.NET AJAX
    A post that describes how to integrate with the browser history and back/forward buttons. By default Silverlight doesn't support this, but using the HTML Bridge and ASP.NET AJAX you can easily add back/forward navigation and bookmark support to your Silverlight application.
  • WCF Authentication Services, Silverlight and smelly cookies
    One of the great strengths of Silverlight 2 is the ability to easily port your application to the full version of WPF if the browser sandbox becomes to limiting. One of the issues I ran into while porting the Dive Log application to WPF was cookie based authentication against my web services. This posts shows how to authenticate against a ASP.NET Membership Provider from WCF.
  • Porting the Silverlight Dive Log application to WPF
    Once I had authentication working in WPF porting the actual Dive Log application was really easy. It probably didn't take more than a couple of hours, and this post describes some of the things I ran into while porting the app.
  • Printing in Silverlight 2 using CSS and ASP.NET AJAX 4
    Printing is a core requirement in many business applications. The Silverlight 2 printing support out of the box is really limiting, but using the HTML Bridge you can provide a better printing experience for your application. The post discusses different printing strategies, and show how to use ASP.NET AJAX 4 to generate HTML on the client that can be printed using CSS print style sheets.

Posts related to the YouCard application

  • YouCard Re-visited: Implementing the ViewModel pattern
    The YouCard application was a demo I wrote for REMIX Australia back in May. The focus was on the UI side of things, and initially I didn't pay too much attention to the architecture of the application. In this post I go back and refactor the code to use the Model-View-ViewModel / Presentation Model pattern.
  • YouCard Re-visited: Implementing Dependency Injection in Silverlight
    Inversion of Control using Dependency Injection is a really popular and powerful software pattern. It helps you separate your concerns, keep your code testable, loosely coupled and more flexible. In this post I show how you can use Dependency Injection in a Silverlight context using the Ninject framework. The post focuses on how Dependency Injection, combined with the MVVM/Presentation Model pattern can make your code easier to use for UX designers. By using mock-objects that provide design-time test data when the code is consumed inside Expression Blend the job of designing the UI, setting up Data Binding and Data Templates becomes allot easier.

Posts about testing, the HTML Bridge and other tips and tricks

  • Webcam in Silverlight 2 - MacGyver style!
    Silverlight 2 does not support webcam or microphone like Flash does. But if you put on your MacGyver hat, and use the HTML Bridge you can get some basic web cam support in Silverlight. This post shows how you can integrate Silverlight 2 and Flash using JavaScript. The example shows how to capture still images from the webcam in Flash, and use the images in Silverlight.
  • Unit testing asynchronous Silverlight code
    I'm a big fan of the Silverlight Testing Framework and how it support more advanced scenarios like testing asynchronous code. This post shows how to asynchronous features of
    the testing framework to test code that talks to Twitter and Flickr.
  • Silverlight 2 Continuous Integration Testing using WatiN
    Continuous Integration is a great practice I try to use on every project I'm involved with. In essence it's about automating what can be automated of your build- and deployment process. A common thing to integrate is automated unit testing on every checking. The problem is that the Silverlight Testing Framework has to execute inside the browser, making it more challenging to integrate it to an automated build process. This post shows how to use WatiN (Web Application Test in .NET) to drive Internet Explorer and detect if the Silverlight tests executes successfully or not. Using this technique you can call your Silverlight tests from a nUnit test, something that makes it allot easier to integrate into your build process.
  • Efficient testing in Silverlight 2 using tags
    The Silverlight Testing Framework makes it easy to write Unit Tests, Integration Tests and User Interface/Smoke Tests. However, you might not want to execute your integration tests every time you change your code. By using the new tagging feature you can categorize your tests and execute only tests that match a certain tag. The post shows how to pass in a tag from the query string to control which tests to execute.
  • Configuring Silverlight 2 applications using the WCF configuration file
    Silverlight 2 uses a configuration file for all it's WCF service references. It does not have the full configuration API from the .NET 3.5 Framework. However, there is nothing stopping you from adding your own custom XML elements to the configuration file, and write code to read it. This post shows how to add an appSettings-element to the configuration file, and build a class that looks and feels like the .NET Configuration Manager.

One of the frequently asked questions on forums, blogs and by conference attendees is how implement printing in Silverlight applications. Out of the box Silverlight 2 does not have any printer specific APIs, and it’s up to you as the developer to figure out how to deal with printing. If you use the print button in Internet Explorer 7 to print you’ll get a simple rendering of the page. If you try to print from Firefox or Safari you’ll get nothing but a blank page. Printing is a core requirement in many business applications and something you need to be addressed if you’re going to build a Silverlight 2 application. In this blog post I’m going to cover different strategies for printing, and show how we can use the HTML Bridge combined with some of the new features in ASP.NET AJAX 4.0 to implement printing from a Silverlight 2 application.

Print Preview of Silverlight content in IE7

Print preview from the Dive Log application. The Silverlight control is stretched since the container is sized to 100% width and height, and the print preview is in portrait mode. This is probably not what the user wants to print anyway.

Printing strategies

When dealing with printing in Silverlight, or perhaps in web applications in general, you have two main options; generating printouts server side or client side.

When building applications you often want to have printout reports that differ from the actual markup making up the UI of the application. In those cases a common solution for printing is to open a pop-up window that contains a server generated report ready to print. The report can be in any format depending on your requirements. You can show a PDF or XPS document, a Word document, or just a plain HTML document. When implementing server side generation of reports you are not limited to what’s available in the browser, and can choose whatever technology you want. You can use plain ASP.NET to generate HTML, or you can use a more advanced reporting solution such as SQL Reporting Services to generate PDF documents on the fly. The drawback of using server side generated reports for printing is that the user has to click a separate print button in your application to bring up the report. If the user simply clicks the print button in the browser toolbar they will get whatever HTML is available in the browser. This breaks the default user interaction models and is something we should try to avoid if possible. You’re also depending on server side resources to generate the report instead of leveraging the power of the client computer.

Client side printing simply means using the built-in functionality of the browser to provide printing in your application. For most content-centric sites, like blogs and news papers, this is the most obvious solution as the entire HTML is already available in the browser. However, you probably don’t want to print things like navigation elements or large header graphics. To solve this all modern browsers supports separate CSS style sheets for print. This enables the developer or designer to customize the look and feel of the page when printed. You can use CSS to hide navigation elements, large graphics, or other parts of the page you don’t want to include in your printout. This is great for HTML pages, but how does this apply to Silverlight 2 applications?

Silverlight is embedded onto the page using an object-tag, normally sitting inside some div-container. This allows us to apply CSS styles against the Silverlight container. In our CSS print style sheet we simply set the visibility to none to hide the Silverlight content when printing the page. At the same time we can change the visibility of another div-container that was hidden in the screen style sheet, but is now visible when printing the page. This enables us to swap visibility between the Silverlight application and other HTML content sitting behind it. Now we just need to populate this HTML element with meaningful content when printing. The way you interact between Silverlight 2 and the browser is through the HTML Bridge. The HTML Bridge lets you invoke JavaScript functions or manipulate the HTML-DOM from managed code in Silverlight 2. Using this API we can dynamically generate HTML on the client to populate the print div-container. The visibility and style of the printout is controlled by the print style sheet. The next question is how to best generate HTML from Silverlight 2. You have a couple of options;

  • Concatenate strings using the StringBuilder
    The perhaps most straight forward approach would be to write code that builds up a big HTML string in Silverlight 2, and then set the InnerHtml property of the container using the HTML Bridge. This would work just fine, but string concatenation is hard to maintain and easily leads to spaghetti code.
  • Use LINQ to XML to generate HTML
    In many cases this would be a good option as you could easily write LINQ queries against your objects, and then use LINQ to XML to dynamically build up the HTML document. This would be cleaner and easier to test and maintain than concatenating strings. The problem with generating the printout through code is that the look and feel of the printout is part of the user experience, and something that should be owned by the UX team and not the developers. Having to change LINQ to XML code to update report is not very flexible or designer friendly.
  • Use Client-side HTML controls for Silverlight 2
    Jeff Wilcox, the guy behind the Silverlight 2 Testing Frameworks, wrote an interesting post a few days back about a Client-side HTML controls library for Silverlight 2. This is something Jeff wrote for the testing framework to generate the test-report. He had the same problem of dynamically generating HTML from Silverlight, and solved it by implementing an abstraction layer on top of the HTML Bridge to build a client-side HTML control library. The library is built by extending the HtmlElement class to build higher level elements like Button, TextBox, Div, Headings, and even complex controls like a progress bar. This gives you an ASP.NET-like programming model running on the client. You can write clean, testable code against the controls, but you still have to build your reports through code. This makes things hard for your designers. The controls are currently only available through the testing framework, something that could make it hard to use in a production environment. But Jeff definitely got some interesting ideas around creating HTML content on the client that is well worth checking out.
  • ASP.NET AJAX 4.0 Client Templates
    An new and really interesting way of generating HTML on the client is using the new Client Templates introduced in the ASP.NET AJAX 4.0 preview release. The client templates let you define HTML fragments containing JavaScript binding expressions. The templates can later be applied to a JavaScript array to generate HTML on the client. This allows you to keep the HTML outside of your Silverlight code, and the only thing you have to pass over the HTML Bridge is the objects you want to use for your printout. This gives your designers the flexibility to work on the HTML and CSS for the printout while keeping your Silverlight 2 code nice and tidy. This is the approach I’ve taken for adding print support to the Dive Log example application.

Printing using ASP.NET AJAX 4.0 Client Templates

One of the really interesting features of the ASP.NET AJAX 4.0 preview is client templates. This enables you to write HTML fragments containing JavaScript binding expressions. The templates can be applied to JavaScript arrays to generate HTML on the client. I would recommend checking out Bertrand Le Roy’s two part blog post for a good introduction to client templates. Scott Hanselman also did a post showing how to use client templates together with jQuery to build dynamic HTML in an AJAX application. The October issue of MSDN Magazine also got a good article about new AJAX support for data driven web sites. The ASP.NET AJAX 4.0 is preview technology and things are likely to change. However the client template script is just a 50KB JavaScript file so using it shouldn’t make a big impact on your application.

The printing user experience I want to achieve for the Dive Log application is really simple. I don’t want to add a print button to the Silverlight 2 interface. Instead all printing should be done through whatever functionality is available in the browser. Most likely by clicking the print-button in the toolbar, or going to the file menu and selecting print or print preview. The printout shouldn’t contain the Silverlight 2 user interface. Instead it should contain a HTML table listing all logged dives.

The first thing we need to do is include two CSS style sheets, one for print and one for screen. The style sheets are responsible for toggling between showing/hiding the Silverlight 2 container and the print container.

Seperate style sheets for print and screen.

I use the ASP.NET Silverlight Control to render the HTML needed to show the Silverlight 2 application. Underneath the Silverlight control I have a separate HTML-div that will be the container for the dynamically generate print HTML.

Silverlight 2 container

The most interesting part of the print implementation is the client template used to generate the HTML. The meat of the template is a plain HTML table with columns for each of the fields we want to use from the dive log. The body of the table is marked with a special CSS class to indicate that this is a template, and the columns contain JavaScript binding expressions.

ASP.NET AJAX 4 Client Template

To populate the template with data we need some JavaScript. The script is kept in a separate file to keep things nice and clean. The script is responsible for instantiating the template based on the HTML markup. The script also registers a custom markup extension for the format expression used to bind the date column. This shows some of the power of using JavaScript binding expressions, and the extensibility of the client template framework. The final piece of JavaScript is a simple function to bind data against the template. The data is passed in as a JSON string from the Silverlight 2 application, and is de-serialized before the template is applied to the JavaScript array.

JavaScript to populate Client Template (available in seperate download)

The final piece of code needed is the Silverlight 2 code responsible for updating the print template with data. This is done by simply invoking the updatePrint-function passing in a list of Dive object serialized as JSON. The code is added to the View Model and is executed every time Dive Logs are retrieved from the server. The list of dives is serialized to JSON using a simple extensions method.

Using the HTML Bridge to update the print container.

When we run the application and click the print-preview button we no longer get a stretched Silverlight 2 user interface. Instead we get a nice HTML table listing all our logged dives. Since we’re using standard HTML and CSS to do printing it now works in all browsers, and not just IE7 which is the only one currently supporting printing of Silverlight 2 content.

Print preview with custom HTML instead of Silverlight 2 content.

Summary

Printing support is a key feature of most line of business application. Unfortunately this isn’t one of the strong sides of Silverlight 2. Hopefully this will improve in future versions of Silverlight. Microsoft hasn’t made any announcements, but I hope for better support for rich text and text layouts. WPF already has great support for documents, and hopefully some of these features will make it into Silverlight. But for now we have to use existing web technologies to solve printing.

In many cases server side generated report will be a good option. Using the HTML Bridge you can easily bring up a pop-up window where you pass in URL parameters to render the report. However, in some cases you should consider providing a good client side printing experience. Hopefully this blog post have given you some ideas to how to implement printing in Silverlight, and at the same shown some of the power of combining Silverlight with existing AJAX technologies. I did run into some minor challenges using this approach. One of them was figuring out when to update the print section with new HTML. Internet Explorer has a onbeforeprint-event you can listen to, but that one is not available in any other browser. Another option would be to listen to mouseout-events to try to detect when the user is moving up to the toolbar (and potentially could be clicking the print button). Non of these techniques where reliable enough, so I decided to simply update the content every time it's persisted/loaded from the server. This could lead to some inconsistence if the user edits a dive and click print before saving it back to the server. How you deal with this would depend on your application and requirements.

One added benefit to this approach is that you could render the initial HTML content of the print container on the server using ASP.NET. This would give search engines like Google something to index, making your Silverlight 2 application searchable. The search engines wouldn’t execute your Silverlight or JavaScript code, so this would only work for the initial rendering of the page.

I will post the updated version of the Dive Log application and source code tomorrow when Microsoft, according to rumors, will be releasing Silverlight 2.

Introduction

I have previously blogged about the Silverlight testing framework that was originally released as part of the Silverlight 2 Beta 1 control source. Jeff Willcox, the lead developer on the framework, recently announced an updated version of the framework for the Silverlight 2 Release Candidate. The updated version contains several interesting new features, which Jeff has covered in a great thorough blog post. I’m not going to re-iterate the feature list in this post, but rather focus on the one of the new features; tagging of tests.

Types of automated testing

Automated unit testing of code has become a common development practice, and as developers we have a wide variety of frameworks to pick from to help us do testing. A common misperception is that any test written using a testing framework is a unit test. That is not necessary true as there are multiple other types of test you can write for your code. Phil Haack, one of the program managers on ASP.NET MVC, wrote about the boundaries of unit tests on his blog a few months back. I recommend this post as a good overview of some of the considerations you should make when writing unit tests.

I’m quickly going to list the types of tests I normally write when building Silverlight applications.

  • Unit Test
    Tests a single unit of work. In most cases a single method in a single class. Normally don’t touch the database, the file system or the network. Should execute quickly with no side effects (changed global state).
  • Integration Test
    Tests how multiple classes integrate with each-other, or how a class integrates with the environment. I.e. parsing of an XML file, reading/writing to a database, or accessing data on the network.

  • Smoke Test
    Simulates an user interacting with the application. Tests multiple classes and can cross boundaries such as network, file system or database. In many cases you write your smoke tests by automating the user interface.

Even if your tests aren’t a true unit tests according to the list above, it’s perfectly fine to use a testing framework like nUnit to write your integration- or smoke tests. There are other types of tests as well, i.e. performance tests, stress tests and acceptance tests. For these types of tests you often use different tools or extensions to your testing framework.

One of the considerations you should make when writing your tests is to keep your unit, integration and smoke tests separated. You should try to keep your unit test running as quickly as possible, something that is easier to achieve if you focus on not crossing any process boundaries. If testing becomes slow and tedious developers might start cheating and not run the test suite as they change code. One way to separate your tests is to have different projects for each type of tests. This is a good solution in many cases, but for smaller projects (like all of my Silverlight demo applications) this may lead to a cluttered project structure. In the Silverlight testing framework you can organize your tests in a different way by adding tags to test classes and test methods.

Tagging tests

One of the new features that were introduced in the latest version of the Silverlight Testing Framework is support for tags. You can apply multiple Tag-attributes to any test class or method in your test suite. The Tag-attribute takes accepts a string, so it is up to you to decide how to organize your tests. As an example for this post I am going use the YouCard application I built for REMIX. The tags I am going to apply are based on the types of tests I listed above; Unit, Integration and Smoke. The YouCard test suite isn’t too big and only got 13 tests in it. But it got a little bit of everything, so it should be a good example.

The most obvious candidate for being tagged as a unit test is the value converters tests. A value is like a mini-adapter you can apply during data binding to convert from one value to another. It got two simple methods, Convert and ConvertBack, and no external dependencies.

Test tagged as unit test

The YouCard application uses the Model-View-ViewModel pattern, so the next set of tests to be tagged as a unit test is the ViewModel tests. The ViewModel class has two dependencies to a Flickr service and a Twitter service. Because these dependencies are implemented as interfaces and injected in the ViewModel constructor I can supply test mocks, making this a pure unit test and not an integration test.

Now that we’ve identified some unit tests it’s time to show some examples of integration tests. The two most obvious candidates are the classes responsible for accessing the Twitter and Flickr APIs. Both implementations are based on an interface, making it easy to mock the dependency when testing the ViewModel. However, we still want to write tests to verify that the code downloading and parsing the XML from Twitter and Flickr works as expected. This means accessing the network, and thus crossing the boundaries of what we consider a unit test.

Test tagged as integration test

The final type of test we want to identify and tag is a smoke test. The Silverlight Testing Framework runs inside the browser with full access to the Silverlight runtime, making it easy to write user interface tests. The YouCard test suite has one smoke test simulating a user entering Twitter usernames into the textbox and hitting the add-user button. The test waits about a second between each user interaction, and it uses real implementations of both the Twitter and Flickr interfaces. This makes the test fairly slow to execute, but still valuable as it gives us a verification that the application works as a whole when all the pieces are coupled together.

Executing tests based on tags

Now that the tests are categorized using tags, how do we execute specific tests based on the tags? In the Silverlight Testing Framework you create the test page in the Application Startup event in the application class. In CreateTestPage method accepts a UnitTestSettings object you can use to configure the test framework. One of the properties on the settings object is a TagExpression property. The name of the property hints that we can supply more than the name of a simple tag. Jeff hasn’t documented this feature yet, so I don’t know the limits of the expressions you can create. You can do things like “!Unit” to execute all tests except the once tagged as “Unit”. I don’t know if you can use more complex expressions and combinations of tags. But in most cases supplying a single tag should be enough.

Configuring test framework in Application Startup

Since configuration of the test framework is done through code it’s easy to make the tag expression dynamic. The example code looks for an initialization parameter called tag, and if found its value is applied as the tag expression. Initialization parameters are passed in when the Silverlight object is created in on the page. If you are using HTML to create the object you add the initialization parameters as a param-element to the object-tag. If you use the ASP.NET Silverlight server control you set the InitParameters property. In this example I have a Silverlight and some ASP.NET code to check the query string. If the query string contains a tag-element the value is passed to the Silverlight control as an initialization parameter. Using this technique you can simply change the URL to execute your test suite with different tag expressions applied.

Passing a tag from the query string to the init parameter.

To execute the code simply navigate to the page hosting the Silverlight tests. By default it will execute all tests, but if you add a tag-parameter in the query string you can control which tests to execute.

Executing tagged Silverlight tests.

Summary

The updated version of the Silverlight Testing Frameworks got lots of new useful features. Support for tagging is one of them. Hopefully this post gives you an introduction to how you can use tags to organize your tests. The deployed version of the DiveLog and YouCard application use this technique, and if you want to see how the test framework executes tests just click one of the links below.

For a little more than a week ago Microsoft released a Release Candidate of Silverlight 2. I’m not going to talk too much about this release, as it has been covered in great detail in the blogosphere. I have now updated my Silverlight 2 sample applications from Beta 2 to the Release Candidate. The RC is not a public release, and is intended as an interim release to give developers some time to get ready for the final release, which is expected shortly. You are not supposed to deploy RC versions of your Silverlight applications to the public, as this could fragment the user base even more and give a poor user experience. However, since the audience of this blog is mostly developers I’ve decided to uploaded fresh RC versions of my sample applications.

I didn’t bump into too many issues in the update. Most of the changes where small XAML modifications now that the ContentPresenter control derives FrameworkElement instead of Control. I discovered that Blend 2.0 SP1 Pre View did a far better job than Visual Studio 2008 to help me work out XAML changes.

The only real issue I ran into was my use of user control inside a DataTemplate in the YouCard application. I have a list of User objects that is bound to an ItemsControl. A common technique to keep the XAML clean is to use a UserControl inside a DataTemplate. That way you can encapsulate all the XAML needed to represent one item in a list into a separate control. In Beta 2 you had to explicitly set the DataContext on your user control to pass the object you want to display in your DataTemplate. If you do that in the RC your binding will fail. If you try to set a breakpoint and debug the DataContext property of your user control you will discover that it’s always null. It took some time to figure out the problem, but the solution was really simple. You simply don’t need to specify the DataContext for your user control inside the DataTemplate. The DataContext will automatically be set for you.

Code illustrating my DataContext problem.

I’ve uploaded new versions of YouCard, DiveLog and Webcam POC to my test page. The source code is available in my Code Samples SkyDrive folder. Now we just need to wait a few more weeks for the RTW!


<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910