Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ListBox and Panels in WPF

0.00/5 (No votes)
26 Sep 2013 1  
This tip shows the different results of using a ListBox in different panels, and the effects on scrolling.

Introduction

This tip shows the different results of using a ListBox in different panels, and the effects on scrolling.

Background

I've been designing an application and ran into an issue with a ListBox that wasn't having a ScrollViewer. A quick search on stackoverflow gave me the answer, but in case anyone else wants to have a look and see the differences and/or play around with this, here's the code/demo I came up with.

Using the ode

I'm using WPF 4 under Visual Studio 2012, with the MVVM Light package.

The RandomHelper was taken from here.

You can simply compile and run the code, or have a look for the .exe in the /bin/debug folder.

The main view model holds a ContentControl that points to a second ViewModel that holds the ListBox.

<Window x:Class="TestListBox.MainWindow"
       ...>
       
    <Window.Resources>
        ...
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        
        <TextBlock ...</TextBlock>
        <Border  ...>
            <ContentControl Content="{Binding Current_VM }"></ContentControl>
        </Border>
    </Grid>
</Window>

The second view model hosts the three panels inside a grid, to show different behavior:

    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="*" /> // row 0
            <RowDefinition Height="*" /> // row 1
            <RowDefinition Height="*" /> // row 2
            <RowDefinition Height="*" /> // row 3
        </Grid.RowDefinitions>
        
        <Grid Grid.Row="0" ... >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
              </Grid.RowDefinitions>
            <ListBox ItemsSource="{Binding MyCol}" Grid.Row="1" />
        </Grid>

        <StackPanel Grid.Row="1" ... >
            <ListBox  ItemsSource="{Binding MyCol}" /
        </StackPanel>

        <DockPanel Grid.Row="2" ... >
            <ListBox  ItemsSource="{Binding MyCol}" /
        </DockPanel>

        <a:ApexGrid Grid.Row="3" ... >
            <ListBoxItemsSource="{Binding MyCol}" Grid.Row="1" />
        </a:ApexGrid>
    </Grid>

The results look like:

As you can see, having a ListBox in a StackPanel causes the ScrollViewer to disappear, since the StackPanel gives its children the entire size they need, rendering the collection without the ScrollViewer.

Points of Interest

If you're using ContentControl in WPF, and you're planning to have collections with scroll viewers, you might want to stick to Grids or DockPanel and avoid StackPanels (unless you want to wrap them in ScrollViewers, or want to give the controls specific height dimensions).

If you're new to MVVM, you might want to look at the source code and notice that Blendability happens with the use of the (IsInDesignMode) statement in InnerControlViewModel.

if (IsInDesignMode)
{
    Design code goes here ...
}
else
{
    Runtime code goes here...
}

So you can get an idea of what runtime data will look like without needing to actually run the code. (A good place to start looking at MVVM is Lauren Bugnion's site here.

History

  • V. 1 -> Original post
  • V. 1.1 -> Added an ApexGrid to the example, and updated the screenshot
  • V 1.2, Dec. 2nd, 2014 -> Updated code , downloads & fixed some typos.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here