Bookmark and Share Share...    Subscribe to this feed Feed   About me...


ItemsControl

How to automatically scroll to the last item

 
<ListBox l:ItemsControlHelper.ScrollToLastItem="true" />
 
 


 
public static class ItemsControlHelper
{
    public static readonly DependencyProperty ScrollToLastItemProperty =
        DependencyProperty.RegisterAttached("ScrollToLastItem",
            typeof(bool), typeof(ItemsControlHelper),
            new FrameworkPropertyMetadata(false, OnScrollToLastItemChanged));
 
    public static void SetScrollToLastItem(UIElement sender, bool value)
    {
        sender.SetValue(ScrollToLastItemProperty, value);
    }
 
    public static bool GetScrollToLastItem(UIElement sender)
    {
        return (bool)sender.GetValue(ScrollToLastItemProperty);
    }
 
    private static void OnScrollToLastItemChanged(DependencyObject sender, 
                            DependencyPropertyChangedEventArgs e)
    {
        var itemsControl = sender as ItemsControl;
 
        if (itemsControl != null)
        {
            itemsControl.ItemContainerGenerator.StatusChanged += 
                     (s,a) => OnItemsChanged(itemsControl,s,a);
        }
    }
 
    static void OnItemsChanged(ItemsControl itemsControl, object sender, EventArgs e)
    {
        var generator = sender as ItemContainerGenerator;
        if( generator.Status == GeneratorStatus.ContainersGenerated )
        {
            if (itemsControl.Items.Count > 0)
            {
                ScrollIntoView(itemsControl, 
                 itemsControl.Items[itemsControl.Items.Count - 1]);
            }
        }
    }
 
    private static void ScrollIntoView(ItemsControl itemsControl, object item)
    {
        if (itemsControl.ItemContainerGenerator.Status == 
            GeneratorStatus.ContainersGenerated)
        {
            OnBringItemIntoView(itemsControl, item);
        }
        else
        {
            Func<object, object> onBringIntoView = 
                    (o) => OnBringItemIntoView(itemsControl, item);
            itemsControl.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, 
                  new DispatcherOperationCallback(onBringIntoView));
        } 
    }
 
    private static object OnBringItemIntoView(ItemsControl itemsControl, object item)
    {
        var element = itemsControl.ItemContainerGenerator.
                 ContainerFromItem(item) as FrameworkElement;
        if (element != null)
        {
            element.BringIntoView();
        }
        return null;
    }
}
 
 



 Comments on this article

Show all comments
Kyaw Wunna
Commented on 12.March 2010
Hello, I just found the coding error when I use this Dependency property tutorial in the .xaml page. I used separate class for "ItemsControlHelper".

These are as follow:

1. The property 'ItemsControlHelper.ScrollToLastItem' does not exist in XML namespace
2. Name 'l.ItemsControlHelper.ScrollToLastItem' is not a valid XAML name.
3. The attachable property 'ItemsControlHelper' was not found in type 'l'.

If possible, please let me know how to fix it. Thanks
Yuri
Commented on 29.June 2010
it will not work with logical scrolling (VirtualizingStackPanel.IsVirtualizing="True")
chet
Commented on 1.July 2010
@Kyaw Wunna
you must reference the namespace
xmlns:l="clr-namespace:[namespace of ItemsControlHelper]"
chet
Commented on 1.July 2010
It can't scroll to the first item ever..cause of scroll the bar will fire itemsControl.ItemContainerGenerator.StatusChanged several times,one generator.Status == GeneratorStatus.ContainersGenerated...why?
chinni
Commented on 2.July 2010
Hello,im not able to set ItemsControlHelper.ScrollToLastItem="true"

Name
E-Mail (optional)
Comment
About Christian Moser