Welcome to MSDN Blogs Sign in | Join | Help

Marcelo's WebLog

Improving the world one entity at a time
StackPanel, DockPanel and scrolling items

I spent a little bit of time with this the other day, and I thought I'd pass the learnings on, in hopes it helps someone.

This is the layout what I was trying to accomplish with WPF. In a section of my window, I wanted a bit of text at the top, and then the rest filled with items. The items in this case were bits of XML with an item template that created a nice representation, but for this post we'll just use buttons, which have the same effect.

My initial XAML looked like this. You can try pasting these into XAMLPad to follow along (and add more buttons or resize the window so all buttons won't fit in the view).

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<StackPanel>
 <ItemsControl>
  <Button>Button</Button>
  <Button>Button</Button>
  <Button>Button</Button>
  <!-- ... -->
 </ItemsControl>
</StackPanel>
</Grid>

This is all well and good, but some of the Buttons are just clipped from the window and you can't get to them. This is because the ItemsControl doesn't have the built-in ability to scroll its contents, so I decided to go ahead an add a wrapping ScrollViewer.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<StackPanel>
 <ScrollViewer>
  <ItemsControl>
   <Button>Button</Button>
   <Button>Button</Button>
   <Button>Button</Button>
   <!-- ... -->
  </ItemsControl>
 </ScrollViewer>
</StackPanel>
</Grid>

This produces a very confusing situation, in which the scroll viewer is present, but the scroll bar is disabled and goes off the window.

After looking at this for a while, I realized that the problem is that the StackPanel doesn't constrain the size of its children. So if the scroll viewer wants to be huge so it doesn't have to, the StackPanel will arrange it so, even if it clips.

The solution then was to switch to something that did constrain its children. In particular, a DockPanel is great, as it will size the last child to occupy all remaining space.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<DockPanel>
 <ScrollViewer>
  <ItemsControl>
  <Button>Button</Button>
  <Button>Button</Button>
  <Button>Button</Button>
  <!-- ... -->
  </ItemsControl>
 </ScrollViewer>
</DockPanel>
</Grid>

Now I have a scroll viewer with an enabled scroll bar, which allows me to get to all the buttons.

Enjoy!

Posted: Tuesday, June 09, 2009 2:00 PM by marcelolr
Filed under:

Comments

edddy said:

Good to know. Thanks for sharing.

# June 9, 2009 8:10 PM

odahan said:

If you suppress the stackPanel (or the DockPanel), all is working fine with just the ScrollViewer.

So why adding these containers since they are not useful ?

I certainly missed something :-)

# June 9, 2009 10:20 PM

marcelolr said:

Good point, odahan. :)

The original scenario was more complicated though - this was just a small markup of what I was trying to do.

If you use XAMLPad a lot, one thing to note is that the 'preview' section *is* embedded in a larger layout context, so results may very if you take the markup and just make it the top-level thing in a Window. Haven't actually tried this to see if it applies in this case though, but again it was just for 'educational purposes'.

Thanks for the clarification!

# June 11, 2009 1:27 AM

odahan said:

Ok, thanks Marcelo.

Perhaps the testing context has been to much simplified to see really what problem the DockPanel is solving in your sample.

But it's nice to see how all these containers are playing together. WPF layout can be sometimes a bit confusing.

(I use very few the xamlpad, I prefer Kaxaml, but i tested your code with xamlpad to be in the same test condition. I tried also using Kaxaml, resulting layout is identical).

# June 11, 2009 9:19 AM

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout

# June 11, 2009 10:41 AM

Torbjorn Berglund said:

I ran into the same problem and started on a custom panel:

http://www.codeproject.com/KB/WPF/const_panel.aspx

I could have used a Grid instead, but I wanted an easy stack-like interface.

# June 13, 2009 3:31 PM

marcelolr said:

@odahan - Kaxaml is pretty cool, but I tend to rely on XamlPad out of inertia - it's there with the SDK, which will typically be on any dev machine around here.

@Torbjorn - nice customer panel. I always feel that while some of the layout behaviors one might get are a bit obscure, doing custom layout that plays nice with the rest of the architecture tends to show up as a pretty elegant solution. Good stuff!

# June 13, 2009 10:24 PM
New Comments to this post are disabled
Page view tracker