Home > DeveloperSection > Forums > Listbox ScrollIntoView doesn't work for variable height items
jayprakash sharma
jayprakash sharma

Total Post:117

Points:821
Posted on    September-21-2013 6:51 AM

 WPF WPF 
Ratings:


 1 Reply(s)
 1392  View(s)
Rate this:

I have a listbox that various items are added to. When a new item is added to the listbox, I need to scroll that item into view (basically scroll to the bottom).

I've tried the solution from WPF ListBox Scroll when item added and also from this blog post

However, neither solutions work because my listbox contains variable height items. If I hack my listbox items templates to have a fixed height instead, then it seems to work. Here is an example of one of my item templates:

<DataTemplate x:Key="StatusMessageTemplate">

    <Grid Grid.Column="1" VerticalAlignment="top" Margin="0,5,10,0">

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="*"/>

            <ColumnDefinition Width="*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition Height="20"></RowDefinition>

        </Grid.RowDefinitions>

        <TextBlock Text="{Binding Path=MessageText}" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" FontWeight="Bold" Foreground="{DynamicResource LightTextColorBrush}"/>

        <TextBlock Text="{Binding Path=created_at, StringFormat=t}" Style="{StaticResource Timestamp}" TextWrapping="Wrap"  HorizontalAlignment="Right" Grid.Row="0" Grid.Column="1"/>

    </Grid>

</DataTemplate>

How can I make the new items scroll into view regardless of their height?



Sumit Kesarwani

Total Post:378

Points:2694
Posted on    September-21-2013 7:48 AM

Hi JayPrakash,

I think I have found the problem. Variable height items are not calculated until displayed. So I add a timer to call the ScrollIntoView function. But even that didn't work well, so I used the VisualTreeHelper to find the ScrollViewer object and force it to the specific row. Here is the code.

System.Windows.Threading.DispatcherTimer dTimer = new System.Windows.Threading.DispatcherTimer();

     dTimer.Interval = new TimeSpan(0, 0, 0, 0, 200); // 200 Milliseconds

     dTimer.Tick += new EventHandler(

        (seder, ea) =>

        {

           //Verses.ScrollIntoView(Verses.Items[itemIndex]);

           for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Verses); i++)

           {

              DependencyObject depObj = VisualTreeHelper.GetChild(Verses, i);

              if (depObj is ScrollViewer)

              {

                 ScrollViewer sv = depObj as ScrollViewer;

                 sv.ScrollToVerticalOffset(itemIndex); // Zero based index

                 break;

              }

           }

           dTimer.Stop();

        });

     dTimer.Start();


Don't want to miss updates? Please click the below button!

Follow MindStick