Fix scrollbars for a dynamic layout in a Listview/ListBox

Some colleagues at work had a problem today with a ListView that had a dynamic layout. Basically we had a ListView that contained an Expander as one of the CellTemplates, the Expander had another ListBox inside that contained several items. The problem with this was that the ScrollBar for the ListView (which contained all the Expanders) was freaking out and behaving like it was drunk. Here is the XAML for this.

   1: <ListView ItemsSource="{Binding}" >
   2:     <ListView.View>
   3:         <GridView>
   4:             <GridViewColumn Header="Test">
   5:                 <GridViewColumn.CellTemplate>
   6:                     <DataTemplate>
   7:                         <Expander Header="Test">
   8:                             <ListBox ItemsSource="{Binding}">
   9:                                 <ListBox.ItemTemplate>
  10:                                     <DataTemplate>
  11:                                         <TextBlock Text="{Binding}"/>
  12:                                     </DataTemplate>
  13:                                 </ListBox.ItemTemplate>
  14:                             </ListBox>
  15:                         </Expander>
  16:                     </DataTemplate>
  17:                 </GridViewColumn.CellTemplate>
  18:             </GridViewColumn>
  19:         </GridView>
  20:     </ListView.View>
  21: </ListView>
  22:
  23: public Window1()
  24: {
  25:     DataContext = new[]
  26:         {
  27:             new [] { 50, 30, 20, 10, 40, 50, 70, 84, 20, 30, 50 },
  28:             new [] { 50, 30, 20, 10, 40, 50, 70, 84, 20, 30, 50 },
  29:             new [] { 50, 30, 20, 10, 40, 50, 70, 84, 20, 30, 50 },
  30:         };
  31:     InitializeComponent();
  32: }

In order to fix this there is a magic trick🙂

All you have to do set an attached  property on the ListView to instruct it’s ScrollViewer that the Content cannot Scroll. so basically the XAML now would look like this

   1: <ListView ItemsSource="{Binding}" ScrollViewer.CanContentScroll="False">
   2:     <ListView.View>
   3:         <GridView>
   4:             <GridViewColumn Header="Test">
   5:                 <GridViewColumn.CellTemplate>
   6:                     <DataTemplate>
   7:                         <Expander Header="Test">
   8:                             <ListBox ItemsSource="{Binding}">
   9:                                 <ListBox.ItemTemplate>
  10:                                     <DataTemplate>
  11:                                         <TextBlock Text="{Binding}"/>
  12:                                     </DataTemplate>
  13:                                 </ListBox.ItemTemplate>
  14:                             </ListBox>
  15:                         </Expander>
  16:                     </DataTemplate>
  17:                 </GridViewColumn.CellTemplate>
  18:             </GridViewColumn>
  19:         </GridView>
  20:     </ListView.View>
  21: </ListView>

As you can see all I changed here is adding the attached property ScrollViewer.CanContentScroll=”False” on the ListView, and viola the scrolling now works correctly🙂

Edit: After having a chat with a fellow WPF Disciple, Andrew Smith, he pointed out that this solution will drop Virtualization support. So if you have a lot of data this is probably not the best solution for you.

5 thoughts on “Fix scrollbars for a dynamic layout in a Listview/ListBox

  1. Pingback: 2008 November 19 - Links for today « My (almost) Daily Links

  2. Pingback: Dew Drop - November 19, 2008 | Alvin Ashcraft's Morning Dew

  3. Pingback: WPF listview « MRoc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s