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.
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.
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.
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.
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.
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.
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.