Я не могу воспроизвести вашу проблему (для меня ListBox
прокручивается до последнего элемента в новой коллекции при изменении ItemsSource
). В любом случае, для прокрутки ListBox
к вершине каждый раз, когда меняется ItemsSource
, вы можете использовать некоторый код позади. Сначала прослушайте изменения в ItemsSourceProperty
, а затем прокрутите ListBox
до верха, как только его элементы будут сгенерированы
Обновление
Сделал прикрепленное поведение, которое делает это, чтобы избежать кода позади. Может использоваться следующим образом
<ListBox ...
behaviors:ScrollToTopBehavior.ScrollToTop="True"/>
ScrollToTopBehavior
public static class ScrollToTopBehavior
{
public static readonly DependencyProperty ScrollToTopProperty =
DependencyProperty.RegisterAttached
(
"ScrollToTop",
typeof(bool),
typeof(ScrollToTopBehavior),
new UIPropertyMetadata(false, OnScrollToTopPropertyChanged)
);
public static bool GetScrollToTop(DependencyObject obj)
{
return (bool)obj.GetValue(ScrollToTopProperty);
}
public static void SetScrollToTop(DependencyObject obj, bool value)
{
obj.SetValue(ScrollToTopProperty, value);
}
private static void OnScrollToTopPropertyChanged(DependencyObject dpo,
DependencyPropertyChangedEventArgs e)
{
ItemsControl itemsControl = dpo as ItemsControl;
if (itemsControl != null)
{
DependencyPropertyDescriptor dependencyPropertyDescriptor =
DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ItemsControl));
if (dependencyPropertyDescriptor != null)
{
if ((bool)e.NewValue == true)
{
dependencyPropertyDescriptor.AddValueChanged(itemsControl, ItemsSourceChanged);
}
else
{
dependencyPropertyDescriptor.RemoveValueChanged(itemsControl, ItemsSourceChanged);
}
}
}
}
static void ItemsSourceChanged(object sender, EventArgs e)
{
ItemsControl itemsControl = sender as ItemsControl;
EventHandler eventHandler = null;
eventHandler = new EventHandler(delegate
{
if (itemsControl.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(itemsControl) as ScrollViewer;
scrollViewer.ScrollToTop();
itemsControl.ItemContainerGenerator.StatusChanged -= eventHandler;
}
});
itemsControl.ItemContainerGenerator.StatusChanged += eventHandler;
}
}
И реализация GetVisualChild
private T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}