wpf listview scroll

wpf - Desplácese ListViewItem para estar en la parte superior de un ListView



scroll (1)

En WPF, sé que puedo usar ListView.ScrollIntoView para desplazar un elemento en particular a la vista, pero siempre hará la menor cantidad de desplazamiento para que se muestre el elemento.

¿Cómo puedo hacer que se desplace para que el elemento que quiero mostrar se desplaza a la parte superior de ListView?

He pensado en llamar a ScrollIntoView dos veces, una vez para el artículo que quiero en la parte superior y una para el último elemento mostrado, pero no sé cómo averiguar cuál es el último elemento que se muestra.


Podemos hacer esto obteniendo el ScrollViewer que está presente en ControlTemplate de ListView. Si tiene acceso a un ScrollViewer, hay muchos métodos de desplazamiento diferentes expuestos.

Primero, podemos crear un ListView al que queremos agregar este efecto:

<ListView ItemsSource="{Binding Percents}" SelectionChanged="OnSelectionChanged" x:Name="uiListView"/>


public List<int> Percents { get; set; } public Window1() { InitializeComponent(); Percents = new List<int>(); for (int i = 1; i <= 100; i++) { Percents.Add(i); } this.DataContext = this; }

También necesitaremos algo que podamos usar para obtener el ScrollViewer de ListView. He usado algo similar a esto antes para trabajar con desplazamiento personalizado, y podemos usarlo aquí también.

public static DependencyObject GetScrollViewer(DependencyObject o) { if (o is ScrollViewer) { return o; } for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++) { var child = VisualTreeHelper.GetChild(o, i); var result = GetScrollViewer(child); if (result == null) { continue; } else { return result; } } return null; }

Ahora, solo tenemos que manejar el evento SelectionChanged. Debido a que estamos tratando de desplazar un elemento a la parte superior de la lista, la mejor opción es desplazarse hacia la parte inferior, y luego volver a desplazarse hacia arriba hasta nuestro elemento seleccionado. Como dijiste, ScrollIntoView se desplazará solo hasta que el elemento sea visible, de modo que una vez que el elemento seleccionado llegue a la parte superior a medida que se desplaza hacia atrás, dejará de dejar nuestro elemento seleccionado en la parte superior de la lista.

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { ScrollViewer scrollViewer = GetScrollViewer(uiListView) as ScrollViewer; scrollViewer.ScrollToBottom(); uiListView.ScrollIntoView(e.AddedItems[0]); }