Making an ItemsControl Scroll...



When you don't need the selection functionality of a ListBox it is often best to use a plain ol' ItemsControl; the overhead is generally less and it's just as easy to program against, a win-win situation. The downside is that you can loose a little too much functionality along the way: such as scrolling (doh!).

In this post I describe how to add scrolling to an ItemsControl and the steps I generally go through to replace the template of a control - a hint as to how I broach the scrolling problem :-)

Scrolling an ItemsPanel

Recently, for an application I'm working on, I replaced a ListBox with an ItemsControl, where scrolling was still important, to which I thought "no problem, I'll just add a ScrollViewer to the ItemsPanel" as per my previous post on the matter of replacing panels.

However, the ItemsControl did not like this at all as you have to replace the ItemsPanel with a Panel and only a Panel - which kinda makes sense; but it does up the ante when it comes to the effort involved.

The solution I went for was to change the control template of the ItemsControl and wrap the ItemsPresenter in a ScrollViewer - otherwise the template remains completely unchanged - and bingo! All is well.

Here's a summary of what that looks like, with the new elements highlighted:

<Style TargetType="{x:Type ItemsControl}">
  <Setter Property="Template">
      <ControlTemplate TargetType="{x:Type ItemsControl}">
         <Border ...>
            <ScrollViewer VerticalScrollBarVisibility="Auto">
              <ItemsPresenter ... />

A scrolling ItemsControl, Done! (with a Gordon Ramseyesq intonation)

Adding a Custom ControlTemplate

As a tip to any budding control template hacker, here are the steps I go through when I need to replace a control's template - first and foremost I open "ShowMeTheTemplate", brought to you by Chris Sells and Ian Griffiths as part of their book, Programming WPF (a must have for any serious WPF developer IMHO).

Next, I copy the contents from the relevant pane into a new <Style>; finally I mess with the template as necessary to achieve the required look, layout or both.

It's worth noting that there are a couple of alternate approaches to extracting a template from a control: the primary one I hear about is the use of Microsoft Expression Blend; but a more "developer" focused approach is to use the control template examples documented on the MSDN Web site.

Personally, I prefer the "ShowMeTheTemplate" approach as it does not require another piece of "pay for" software, such as Blend, and it displays a true representation of the template, as opposed to a documented version of the template.

If you know of any other ways then then I'd love to hear from you.


famet said...

Thank you, it helped me a lot!!!

Anonymous said...

Thank you. This was incredibly helpful.

Mel Green said...

Wonderful! Thank you for the post.

e.semog said...

This was a huge time saver for me, and allowed me to ditch the listbox control I was using. I now have a much improved interface that works like I originally intended. Thanks!

TK421 said...

Newbie here to wpf - can you provide the xaml?

Anonymous said...

Thank you thank you thank you. I've been stuck on this all night with all kinds of crazy ideas.