|
|
|
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;
}
}
Last modified: 2010-02-03 14:58:42
Copyright (c) by Christian Moser, 2011.
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"
|
|
|
|
suji | |
|
Commented on 22.November 2010 |
hi, how to use AddText method in ItemControl
|
|
|
|
Don | |
|
Commented on 27.December 2010 |
I think, to make things work, the is a line like
itemsControl.ItemContainerGenerator.StatusChanged = null
missing. Not the finest method to clear the events, but it works.
Nice Text to show the possibillities !
|
|
|
|
m.n | |
|
Commented on 12.May 2011 |
Doesn't work if last item equals to the first, because ContainerFromItem() finds the first item, not the last.
Using item index instead of item itself, solves the problem:
private static object OnBringItemIntoView(ItemsControl itemsControl, int index)
{
var element = itemsControl.ItemContainerGenerator.ContainerFromIndex(index) as FrameworkElement;
if (element != null)
{
element.BringIntoView();
}
return null;
}
Plus change "object item" to "int index" appropriately.
|
|
|
|
|
|