Search code examples
c#wpflistboxscrollviewer

ListBox with GroupStyle scrolls by group, not by item


I have a ListBox with a GroupStyle. If i use the GroupStyle the ScrollViewer of the ListBox scrolls by group rather that item. So if the group has more items than fit on the screen the user never sees the ones off screen. If i comment out the GroupStyle the ScrollViewer works like intened an scrolls item by item. (I added the ControlTemplate to try different things).

<UserControl.Resources>
    <CollectionViewSource x:Key="BusStopsFlattend" Source="{Binding BusStopsFlat}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="CountryCode" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</UserControl.Resources>

<ListBox Grid.Row="1" ItemsSource="{Binding Source={StaticResource BusStopsFlattend}}" Margin="48,0,48,60">
<ListBox.Template>
    <ControlTemplate TargetType="{x:Type ListBox}">
        <ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Disabled">
            <ItemsPresenter />
        </ScrollViewer>
    </ControlTemplate>
</ListBox.Template>

<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid Margin="0,24,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <controls:IconViewbox Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" IconData="{StaticResource IconPathPencilOutline}" IconSize="72" Margin="0,0,24,0" />

            <TextBlock Grid.Column="1" Grid.Row="0" FontSize="32" TextWrapping="Wrap" Text="Name" /> 
            <TextBlock Grid.Column="1" Grid.Row="1" FontSize="22" TextWrapping="Wrap" Text="Address" />
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel />
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

<ListBox.GroupStyle>
    <GroupStyle>
        <GroupStyle.Panel>
            <ItemsPanelTemplate>
                <StackPanel />
            </ItemsPanelTemplate>
        </GroupStyle.Panel>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <TextBlock Grid.Row="0" FontSize="36" FontWeight="Bold" Margin="0,48,0,24" Text="{Binding Name}" />
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListBox.GroupStyle>
</ListBox>

Solution

  • Just set ScrollViewer.CanContentScroll property to False to use physical scrolling instead of logical scrolling. Keep in mind that this will disable virtualization if you decide to use it.