LISTBOX SCROLLINTOVIEW DOESN'T WORK FOR VARIABLE HEIGHT ITEMS

jayprakash sharma

Total Post:117

Points:821
Posted by  jayprakash sharma
WPF 
WPF
 1772  View(s)
Ratings:
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?

  1. Sumit Kesarwani

    Post:378

    Points:2694
    Re: Listbox ScrollIntoView doesn't work for variable height items

    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();

Answer

NEWSLETTER

Enter your email address here always to be updated. We promise not to spam!