The layout system in Silverlight is, in my opinion, one of the key differentiators in presentation engine capabilities from HTML/CSS (on a related note, see my post long ago about my browser/scripting wish list and the references to need for core layout primitives).
The Silverlight platform provides a set of out-of-the-box layouts like Grid, so you don't have to simulate them with low-level absolute positioning, and float/clear css attributes. However, beyond that, you can build your own first class layouts, and in this post I'll discuss the handful of layout panels that I've written for Silverlight.FX, that I've found useful in application building.
Silverlight.FX currently has five layout panels: TilePanel, HStackPanel, VStackPanel (which derive from a base AnimatedPanel), XGrid, and FormPanel. It also has something called TemplatePanel, but I'll discuss that in a separate post, as it does a bit more than layout. I wanted to share a bit of information about the current set of panels, their scenarios and the motivation for them.
XGrid
XGrid derives from Grid, and is there to simply make it easier to specify the rows and columns. Instead of a Grid where you have to write several lines of XAML just to define a set of RowDefinitions and ColumnDefinitions (anyone who has used Grid knows what I am talking about), you can simply write the following XAML:
<fxui:XGrid Columns="20,*,5,350,20" Rows="20,40,*,5,250,20">
<Image Source="/Themes/StoreLogo.png" Grid.Column="1" Grid.Row="1"
Margin="0,4,0,4" VerticalAlignment="Center" HorizontalAlignment="Left" />
...
</fxui:XGrid>
The layout functionality is identical. Personally I believe this is easier to type in and more importantly easier to read and focus on the contents of the Grid, rather than the row/column structure of the Grid (both of which I think are valuable). In all my app building I've been able to completely switch to XGrid, except for once where I had to specify minimum width. I think the native Grid is just fine for those exceptional scenarios.
FormPanel
Grid (and XGrid) are all-powerful, and very general purpose. However, they're not optimized for laying out forms (labels, textboxes etc.). You have to position each control in a specific Grid cell, and you have to specify margins and alignment on each control. Essentially you're mixing a lot of layout details into the content of the Grid, and reducing that would be nice. Secondly the sheer number of Grid.Row/Column/RowSpan/ColumnSpan, Margin, and HorizontalAlignment, VerticalAlignment attributes takes over and makes it harder to see the more meaningful attributes on your Grid's chidren.
This led to FormPanel. This panel intrinsically understands the notion of Labels and associated controls, as well as heuristics to line them and stack them vertically, separated with appropriate margins and alignment. For example, here is a form I have in one of my apps and the associated XAML.
<fxui:FormPanel Width="400" Height="400">
<fxui:Label Text="Title:" />
<TextBox Text="{Binding Project.Title}"
IsReadOnly="True" />
<fxui:Label Text="Keywords:" />
<TextBox Text="{Binding Project.Keywords}" />
<TextBlock Style="{StaticResource deEmphasizedText}"
Text="Individual words separated by spaces" />
<TextBlock fxui:FormPanel.IsLabeled="False"
Text="The project summary should ... paragraph."
TextWrapping="Wrap" />
<fxui:Label Text="Summary:" />
<TextBox Text="{Binding Project.Summary}" />
<fxui:Label Text="Description:"
fxui:FormPanel.LabelPosition="Top" />
<TextBox Text="{Binding Project.Description}"
Height="120" />
</fxui:FormPanel>
I personally like my XAML to be minimal and communicative of actual intent and behavior, rather than appear complicated as a result of a bunch of layout information mixed in. FormPanel derives from Grid, so it doesn't actually need to replicate a ton of layout logic. It inherits all that which keeps size and complexity minimal.
FormPanel interprets Label controls as Labels, and the next control in the collection as its associated control. It provides some attached properties that can be specified on its children to control the layout such as relative positioning of the label, and whether elements span the full width of the container if they don't have a corresponding Label... that sort of thing. The best way to check these out are to look at the doc-comments with the API in class browser.
HStackPanel, VStackPanel
I got tired of having to specify the Orientation property on StackPanel all too often. Beyond that, I really dislike specifying alignments and margins on the children of StackPanel to get reasonable looking UI where controls are correctly aligned and spaced apart, since its mixing layout into content, and that makes it harder to switch layout at a future date.
<fxui:HStackPanel
ChildFlow="Right" ChildAlignment="Center" ChildSpacing="4">
<TextBlock Text="Quantity:" />
<TextBox x:Name="quantityTextBox" Text="1"
Width="50" Height="23" />
<Button Width="75" Height="23"
Content="Add to Cart" />
</fxui:HStackPanel>
Both HStackPanel and VStackPanel derive from AnimatedPanel, which is a base class in Silverlight.FX that makes it simple to create animated layouts if that is desirable for the scenario. The app developer simply needs to turn on animation, and the specific layout panel does not have to deal with the details of animating children, starting/stopping animation, interpolation, easing etc.
TilePanel
TilePanel doesn't exactly fall into the general forms scenarios, but it is nice for showing a set of items that are equally distributed in a tiling fashion.
For example, I can use a TilePanel within an ItemsControl as follows:
<ItemsControl ItemsSource="{Binding Products}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<fxui:TilePanel TileHeight="200" TileWidth="200"
UseAnimatedLayout="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<app:Product />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
To see the layout live in action, check out either Silverlight Store or Flickr Tiles. Basically each child, a tile, is equally sized and is arranged from left to right and top to bottom. This panel also derives from AnimatedPanel, and as such tiles can be animated and eased into the position as the size of the panel changes, or the tiles get re-ordered or added/removed into the UI.
If you're interested in using AnimatedPanel to build a custom panel, or want to see how any of these work under the covers, you can check them out by downloading the sources for Silverlight.FX.
I have a handful of other panels I'd like to add to the framework over time, but I really would like to hear what do you think? What other layout scenarios do you think are interesting for mainline form layout scenarios, where you think a specialized layout panel would help much more than a general Grid? And beyond that, what other layout panels do you think would be most interesting for adding nice visual touches and flair to an application's UX?