Welcome to irritatedVowel.com Sign in | Help

POKE 53280,0: Pete Brown's Blog

Silverlight, WPF, Windows Client Development, Woodworking, .NET Programming, CNC, Nature, and other topics.

Subscribe

Subscribe to my feed
Add to Technorati Favorites

My Book

Order my upcoming book, Silverlight in Action, covering Silverlight 4, ViewModel/MVVM, WCF RIA Services, MEF and more

About Pete Brown

Pete Brown is a Microsoft Developer Division Community Program Manager, focusing on Windows Client Development as well as a former Microsoft Silverlight MVP and INETA Speaker. Pete writes on a number of topics including Silverlight, WPF, .NET, woodworking and working as a consultant in the DC area. read more

Community Events


who's online

AddThis Social Bookmark Button

Silverlight Tip : Nest Another Grid Inside LayoutRoot for Flexibility

This is something I’ve been doing since we first got LayoutRoot, and it has saved me aggravation a number of times. This works in Silverlight 2 and Silverlight 3 (the drop shadow effect in the example below only works in Silverlight 2).

Simply put: I never set column definitions, margins or anything else related to layout directly on layout root. Instead, I nest another grid inside it and work with that.

I was asked if I consider this a preference or a best practice. Given the iterative approach we usually take to designing and developing our apps, I would say this definitely falls under the best practice category.

Here’s an example of the nested grid approach. Note that I didn’t set margins, rows or columns on LayoutRoot.

<UserControl x:Class="PeteBrown.ScratchProject.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <Grid x:Name="LayoutRoot">
        
        <Grid Margin="5">
            <Grid.RowDefinitions>
                <RowDefinition Height="100" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="350" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            
            <!-- Content goes here -->

        </Grid>

    </Grid>
    
</UserControl>

This way, I can easily add a border or other elements later without having to move everything around. Consider the case where you put together this app, and decide you want to put a border around the content. If you defined all the columns and rows directly on layout root, you’d either need to move them all to a second grid now, or make the border the LayoutRoot. But if you made the border LayoutRoot and had code expecting LayoutRoot to be a panel, then you’d have to fix that as well.

Say you wanted to add an interesting background rectangle to your layout. If you set the rows/columns/margins on layout root, you’d have to live within those (with an ugly RowSpan and ColumnSpan setting and negative margins) or again, move the grid down to another level.

Here’s an example of what I’m talking about. As I iterated through this, adding the columns, and then adding the background rectangle, I’d have had to do a lot of shifting if I attached everything directly to LayoutRoot.

image

<UserControl x:Class="PeteBrown.ScratchProject.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <Grid x:Name="LayoutRoot">

        <Rectangle x:Name="BackgroundRectangle"
                   RadiusX="5"
                   RadiusY="5"
                   Margin="10"
                   Fill="#FF323242">
            <Rectangle.Effect>
                <DropShadowEffect BlurRadius="20"
                                  Direction="0"
                                  Opacity="1"
                                  ShadowDepth="0" />
            </Rectangle.Effect>

        </Rectangle>
        
        <Grid Margin="20">
            <Grid.RowDefinitions>
                <RowDefinition Height="100" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="350" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            
            <!-- Content goes here -->
            <TextBlock Text="Here lies the content. May she rest in peace."
                       FontSize="14"
                       Foreground="White"
                       TextWrapping="Wrap"/>
        </Grid>

    </Grid>
    
</UserControl>
Note above that the rectangle sits within LayoutRoot so I don’t have to fiddle with row and column spans, and don’t have to set negative margins. The content sits within the inside grid.

This also gives you the freedom to use something other than a grid (a canvas or stackpanel), while still keeping the LayoutRoot itself as a grid. This may be important to how your application is structured.

  Add to Technorati Favorites
Posted: Monday, March 30, 2009 10:43 PM by Pete.Brown
Filed under: ,

Comments

Andy said:

Nested rules! My code features many 'deep grids', as grids are the easiest way of justifing UIElements and Controls - Left, right, center, top and bottom. This way is rather like the classic tag. Personally, I've avoided stackpanels!
# March 31, 2009 9:39 AM

Rob Burke said:

This got an enthusiastic golf clap out of me :) I have been teased many times during demos for adding Grids inside Grids to future-proof a layout :)
# April 9, 2009 4:42 PM

Paulo said:

Hey there! I was reading your blog and found this post. Very useful. I'm using Silverlight 2 and I can't use the effects on the rectangle. Is there any reason for this? Am I missing something? Cheers
# May 18, 2009 7:18 AM

Pete.Brown said:

@Paulo

Effects were introduced with Silverlight 3; Silverlight 2 doesn't know anything about effects.

Pete

# May 18, 2009 7:28 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the text you see in the image:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS