Page view counter

Silverlight Toolkit: DockPanel

Hi Folks,

I’d like for us to talk about one of the new controls in the Silverlight Toolkit – DockPanel.

In the following article we’ll deep dive into DockPanel and see how it behaves in different situations.

 

 

Setup

1. Create a new project.

File --> New --> Project

Select project type

2. Add a reference to the Silverlight Controls assembly (Microsoft.Windows.Controls.dll) which can be downloaded at http://codeplex.com/Silverlight.

image    image

3. Add a Silverlight Toolkit controls xmlns reference to the XAML page.

image

4. Add a DockPanel to the Page with LastChildFill=False. (we’ll talk about this property later in this article)

<controls:DockPanel LastChildFill="False" />

Here’s the XAML we just wrote:

<UserControl x:Class="SilverlightControlsNovember2008.Page"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Width="400" Height="300"

   xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls">

    <Border x:Name="LayoutRoot" Background="White" BorderBrush="Black" BorderThickness="1">

        <controls:DockPanel LastChildFill="False" />

    </Border>

</UserControl>

(for the purposes of this specific demo, we changed LayoutRoot to be a <Border> and not a <Grid>. That is so we could see the edge of our visual area)

 

 

Docking a single Item

Let’s add a <Button> to the top our DockPanel.

 

<controls:DockPanel LastChildFill="False">

    <Button Content="#1" />

</controls:DockPanel>

 

And here’s a preview through Visual Studio XAML designer:

image

<Button> Fills all the available space given to the control inside our DockPanel.
So actually Button is perfect for us to learn about DockPanel, since it lets us see exactly where the control is and what the available size for it is.

As we can, the <Button> is Docked to the Left of our DockPanel.

Let’s specify a Controls:DockPanel.Dock Attached property value that would allow us to dock items to areas of the DockPanel.

Dock Enum values

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Top" Content="#1" />

</controls:DockPanel>

image

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Right" Content="#1" />

</controls:DockPanel>

image

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

</controls:DockPanel>

image

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Left" Content="#1" />

</controls:DockPanel>

image

 

 

Docking two items to opposite docking areas

Looking at the previous example it’s pretty easy to figure out what the following XAML would look like.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Left" Content="#1" />

    <Button controls:DockPanel.Dock="Right" Content="#2" />

</controls:DockPanel>

image

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Top" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

</controls:DockPanel>

image

 

 

Docking the last item to Center

In our first DockPanel example we’ve set some mysterious LastChildFill property to false.

Let’s set LastChildFill=True and put an undocked button as the last child of the DockPanel.

<controls:DockPanel LastChildFill="True">

    <Button controls:DockPanel.Dock="Top" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

    <Button Content="Filler" />

</controls:DockPanel>

image

It’s important to note that Even if we do set DockPanel.Dock property on the last child of a DockPanel, it would still get filled out if LastChildFill=True.

<controls:DockPanel LastChildFill="True">

    <Button controls:DockPanel.Dock="Top" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

    <Button controls:DockPanel.Dock="Left" Content="Filler" />

</controls:DockPanel>

image

You can see the “DockPanel.Dock=Left” is completely ignored and the Last child is still treated as a filler.

 

 

Docking Defaults (LastChildFill=True, Dock=Left)

By default a DockPanel would always treat the last child as a Filler.

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Top" Content="#1" />

    <Button Content="Filler" />

</controls:DockPanel>

image

And by default, any item not Docked to any area, will be docked to the Left.

<controls:DockPanel>

    <Button Content="#1" />

    <Button Content="Filler" />

</controls:DockPanel>

image

Let’s add a few more items so the Default Left docking would be a bit more visible.

<controls:DockPanel>

    <Button Content="#1" />

    <Button Content="#2" />

    <Button Content="#3" />

    <Button Content="Filler" />

</controls:DockPanel>

image

Essentially, DockPanel by default mimics a Horizontal StackPanel besides the fact that it does treat the last item as a filler.

<StackPanel Orientation="Horizontal">

    <Button Content="#1" />

    <Button Content="#2" />

    <Button Content="#3" />

    <Button Content="Filler" />

</StackPanel>

image

 

 

Docking Multiple elements to the same Docking area

You’ve probably noticed in the previous example that the DockPanel stacks items on the same Area.

Let’s have a look at stacking multiple items on all sides.

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Top" Content="#1" />

    <Button controls:DockPanel.Dock="Top" Content="#2" />

    <Button controls:DockPanel.Dock="Top" Content="#3" />

    <Button Content="Filler" />

</controls:DockPanel>

image

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Right" Content="#1" />

    <Button controls:DockPanel.Dock="Right" Content="#2" />

    <Button controls:DockPanel.Dock="Right" Content="#3" />

    <Button Content="Filler" />

</controls:DockPanel>

image

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

    <Button controls:DockPanel.Dock="Bottom" Content="#3" />

    <Button Content="Filler" />

</controls:DockPanel>

image

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Left" Content="#1" />

    <Button controls:DockPanel.Dock="Left" Content="#2" />

    <Button controls:DockPanel.Dock="Left" Content="#3" />

    <Button Content="Filler" />

</controls:DockPanel>

image

The order in which items are stacked is based on the first rule of DockPanel.

image

The First Rule of Fight Club: You Don’t talk about Fight Club

image

The First Rule of DockPanel: The order of DockPanel Children’s determines their placement based on precedence

 

Admittedly it’s not as dramatic as fight club, but it’s still true.

Consider these trivial DockPanel samples:

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Left" Content="#1" />

    <Button controls:DockPanel.Dock="Left" Content="#2" />

    <Button Content="Filler" />

</controls:DockPanel>

<controls:DockPanel>

    <Button controls:DockPanel.Dock="Left" Content="#2" />

    <Button controls:DockPanel.Dock="Left" Content="#1" />

    <Button Content="Filler" />

</controls:DockPanel>

image image

The #1 and #2 Items are placed based on the order of the DockPanel children.

Although that on the surface they’re both docked to the Left exactly, one has precedence over the other.

The order of DockPanel Children’s determines their placement based on precedence.

 

 

Docking Two elements with intersecting Docking areas

We mentioned Precedence, That is also relevant for Intersecting items.

Have a look at these two DockPanels. 

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Top" Content="#1" />

</controls:DockPanel>

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Left" Content="#1" />

</controls:DockPanel>

 image image

Let’s illustrate how this collision would look like: (done with mspaint, not an actual print-screen)

image

Now, it’s obvious that one of these items would need to get the Top-left corner, but which one?
Let’s write some code, run it and we’ll see.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Top" Content="#1" />

    <Button controls:DockPanel.Dock="Left" Content="#2" />

</controls:DockPanel>

image

And if we change the order of the buttons:

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Left" Content="#2" />

    <Button controls:DockPanel.Dock="Top" Content="#1" />

</controls:DockPanel>

image

So, as we can see – In the first example Button #1 was placed first and it got precedence over Button #2 for the top-left corner.

And in the second example Button #2 was placed first and it got precedence over Button #1 for the top-left corner.

Let’s see this at work with other docking areas.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Right" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

</controls:DockPanel>

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

    <Button controls:DockPanel.Dock="Right" Content="#2" />

</controls:DockPanel>

image image

So, we can clearly see that the order of items in the DockPanel determines who is docked first to where.

 

 

Docking Multiple elements to intersecting Docking areas

Let’s follow up on the last sample with more than one item per docking area.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

    <Button controls:DockPanel.Dock="Bottom" Content="#3" />

    <Button controls:DockPanel.Dock="Right" Content="#4" />

</controls:DockPanel>

image

So, Button #1 is docked first to the bottom area, followed by buttons #2 and #3, and finally Button #4 is docked to the Right.

Let’s put more items on the Right docking area.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

    <Button controls:DockPanel.Dock="Bottom" Content="#3" />

    <Button controls:DockPanel.Dock="Right" Content="#4" />

    <Button controls:DockPanel.Dock="Right" Content="#5" />

    <Button controls:DockPanel.Dock="Right" Content="#6" />

</controls:DockPanel>

image

Continuing for where the last sample left off, Button #4 is the first control docked to the right, followed by Button #5 and finally Button #6.

And we’ll finish this sample by adding Top docked buttons and Left docked buttons.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

    <Button controls:DockPanel.Dock="Bottom" Content="#2" />

    <Button controls:DockPanel.Dock="Bottom" Content="#3" />

    <Button controls:DockPanel.Dock="Right" Content="#4" />

    <Button controls:DockPanel.Dock="Right" Content="#5" />

    <Button controls:DockPanel.Dock="Right" Content="#6" />

    <Button controls:DockPanel.Dock="Top" Content="#7" />

    <Button controls:DockPanel.Dock="Top" Content="#8" />

    <Button controls:DockPanel.Dock="Top" Content="#9" />

    <Button controls:DockPanel.Dock="Left" Content="#10" />

    <Button controls:DockPanel.Dock="Left" Content="#11" />

    <Button controls:DockPanel.Dock="Left" Content="#12" />

</controls:DockPanel>

image

First, Buttons #1, #2 & #3 Get placed on the bottom.

Second, Buttons #4, #5 & #6 get placed on the right, using up remaining height in the DockPanel.

Third, Buttons #7, #8 & #9 get placed on the top, using up remaining width in the DockPanel.

Lastly, Buttons #10, #11 & #12 get placed on the Left, using up remaining Height in the DockPanel (after placing both Bottom and Top buttons).

 

So again – The order of DockPanel Children’s determines their placement based on precedence.

Let’s mix it up a bit by alternating top buttons and left buttons.

<controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Bottom" Content="#1" />

    <Button controls:DockPanel.Dock="Right" Content="#2" />

    <Button controls:DockPanel.Dock="Bottom" Content="#3" />

    <Button controls:DockPanel.Dock="Right" Content="#4" />

    <Button controls:DockPanel.Dock="Bottom" Content="#5" />

    <Button controls:DockPanel.Dock="Right" Content="#6" />

</controls:DockPanel>

image

image 

We can see that items are weaved into the DockPanel, based on their order.

 

 

Spiral Sample

One last final sample for DockPanel is the Spiral sample by Ted Glaza (a developer on the Silverlight Toolkit team) and slightly changed for this blog post.

 <controls:DockPanel LastChildFill="False">

    <Button controls:DockPanel.Dock="Left" Background="LightBlue" Content="#1" />

    <Button controls:DockPanel.Dock="Top" Background="LightCoral" Content="#2" />

    <Button controls:DockPanel.Dock="Right" Background="LightGreen" Content="#3" />

    <Button controls:DockPanel.Dock="Bottom" Background="LightYellow" Content="#4" />

    <Button controls:DockPanel.Dock="Left" Background="LightGreen" Content="#5" />

    <Button controls:DockPanel.Dock="Top" Background="LightYellow" Content="#6" />

    <Button controls:DockPanel.Dock="Right" Background="LightBlue" Content="#7" />

    <Button controls:DockPanel.Dock="Bottom" Background="LightCoral" Content="#8" />

    <Button controls:DockPanel.Dock="Left" Background="LightGray" Content="#9" />

    <Button controls:DockPanel.Dock="Top" Background="LightCoral" Content="#10" />

    <Button controls:DockPanel.Dock="Right" Background="LightGreen" Content="#11" />

    <Button controls:DockPanel.Dock="Bottom" Background="LightBlue" Content="#12" />

    <Button controls:DockPanel.Dock="Left" Background="LightCoral" Content="#13" />

    <Button controls:DockPanel.Dock="Top" Background="LightGoldenrodYellow" Content="#14" />

    <Button controls:DockPanel.Dock="Right" Background="LightYellow" Content="#15" />

    <Button controls:DockPanel.Dock="Bottom" Background="LightGreen" Content="#16" />

    <Button controls:DockPanel.Dock="Left" Background="LightYellow" Content="#17" />

    <Button controls:DockPanel.Dock="Top" Background="LightCoral" Content="#18" />

    <Button controls:DockPanel.Dock="Right" Background="LightBlue" Content="#19" />

    <Button controls:DockPanel.Dock="Bottom" Background="LightGreen" Content="#20" />

    <Button controls:DockPanel.Dock="Left" Background="LightBlue" Content="#21" />

    <Button controls:DockPanel.Dock="Top" Background="LightGreen" Content="#22" />

    <Button controls:DockPanel.Dock="Right" Background="LightCoral" Content="#23" />

    <Button controls:DockPanel.Dock="Bottom" Background="LightYellow" Content="#24" />

</controls:DockPanel>

image

image

Pretty, isn’t it?

 

-- Justin Angel

Microsoft Silverlight Program Manager

Published Thursday, October 30, 2008 6:13 PM by JustinAngel
Filed under:

Comments

# Silverlight Cream for October 31, 2008 -- #415

In this issue: Jeff Wilcox, Jordan Knight, Justin Angel, Imran Shaik, Corey Schuman, Jeff Paries, and

Friday, October 31, 2008 1:48 PM by Community Blogs

# Tweened &raquo; Blog Archive &raquo; Silverlight 2 Toolkit

Pingback from  Tweened  &raquo; Blog Archive   &raquo; Silverlight 2 Toolkit

Saturday, November 01, 2008 12:07 PM by Tweened » Blog Archive » Silverlight 2 Toolkit

# Toolkit posts: &quot;Silverlight in Style,&quot; dependency properties in WPF and Silverlight, and TreeView expansion - Jeff Wilcox

Pingback from  Toolkit posts: &quot;Silverlight in Style,&quot; dependency properties in WPF and Silverlight, and TreeView expansion - Jeff Wilcox

# re: Silverlight Toolkit: DockPanel

Hi Justin,

You have put together a number of very, very good Silverlight Toolkit tutorials - your efforts are very helpful and very appreciated.

An English article index would be very helpful.

Thank you,

David Roh

JK@SilverlightAzure.com

Monday, November 17, 2008 7:22 AM by davidjjon77

# re: Silverlight Toolkit: DockPanel

Any support for splitters and collapsible non-fillers soon, by chance? Or is it already easy to achieve with the grid splitters?

Monday, February 02, 2009 6:36 AM by mepfuso

# Flashxpress &raquo; Silverlight 2 Toolkit

Pingback from  Flashxpress   &raquo; Silverlight 2 Toolkit

Monday, February 16, 2009 8:43 AM by Flashxpress » Silverlight 2 Toolkit