Soy incapaz de reproducir su problema (para mí, la ListBox
se desplaza hasta el último elemento de la nueva colección al cambiar ItemsSource
). De todos modos, para desplazar el ListBox
a la parte superior cada vez que cambia su ItemsSource
puede usar algún código. Primero escucha a los cambios en la ItemsSourceProperty
y luego desplazarse por la ListBox
a la parte superior una vez que sus artículos se ha generado
actualización
Hecho un comportamiento adjunto que hace esto en su lugar para evitar código detrás. Se puede utilizar como esto
<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;
}
}
Y una implementación de 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;
}
¿Entendí bien tu pregunta o estabas buscando algo más? –
@Meleak ¡Gracias! ese enfoque será útil. De hecho, he rastreado el problema hasta un VirtualizingTilePanel que mi ListBox está utilizando y que he tomado de http://blogs.msdn.com/b/dancre/archive/2006/02/16/implementing-a-virtualizingpanel-part -4-the-goods.aspx. El problema se puede replicar en la descarga de muestra desplazándose hacia abajo, y luego reemplazando la colección enlazada con una que contenga un solo elemento. La vista queda en blanco hasta que te desplaces hacia arriba con la rueda del mouse. – devdigital
Encontré una respuesta en http://social.msdn.microsoft.com/Forums/en/wpf/thread/05c5868b-7c91-4726-81fb-9af634c74d4a para VirtualizingTilePanel, pero he cambiado a la virtualización wrappanel desde binarymission - http://www.binarymission.co.uk/binaryvirtwrappanelsl3.htm – devdigital