WPF ListBox Прокрутка для автоматического завершения

В моем приложении у меня есть ListBox с элементами. Приложение написано в WPF.

Как я могу автоматически прокручивать последний добавленный элемент? Я хочу, чтобы ScrollViewer был перемещен в конец списка, когда новый элемент был добавлен.

Есть ли какое-либо событие, например ItemsChanged? (Я не хочу использовать событие SelectionChanged)

7 ответов

Попробуйте следующее:

lstBox.SelectedIndex = lstBox.Items.Count -1
lstBox.ScrollIntoView(lstBox.SelectedItem)


Имейте в виду, что listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); работает только в том случае, если у вас нет повторяющихся элементов. Если у вас есть предметы с тем же содержимым, он прокручивается до первой находки.

Вот решение, которое я нашел:

ListBoxAutomationPeer svAutomation = (ListBoxAutomationPeer)ScrollViewerAutomationPeer.CreatePeerForElement(myListBox);
IScrollProvider scrollInterface = (IScrollProvider)svAutomation.GetPattern(PatternInterface.Scroll);
System.Windows.Automation.ScrollAmount scrollVertical = System.Windows.Automation.ScrollAmount.LargeIncrement;
System.Windows.Automation.ScrollAmount scrollHorizontal = System.Windows.Automation.ScrollAmount.NoAmount;
//If the vertical scroller is not available, the operation cannot be performed, which will raise an exception. 
if ( scrollInterface.VerticallyScrollable )
 scrollInterface.Scroll(scrollHorizontal, scrollVertical);


Самый простой способ сделать это:

if (VisualTreeHelper.GetChildrenCount(listView) > 0)
{
 Border border = (Border)VisualTreeHelper.GetChild(listView, 0);
 ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
 scrollViewer.ScrollToBottom();
}

Он всегда работает для элементов управления ListView и ListBox. Прикрепите этот код к событию listView.Items.SourceCollection.CollectionChanged, и у вас есть полностью автоматическое поведение автоматической прокрутки.


Лучшим решением является использование объекта ItemCollection внутри элемента управления ListBox эта коллекция была специально разработана для пользователей контента. Он имеет предопределенный метод для выбора последнего элемента и сохранения ссылки на позицию курсора....

myListBox.Items.MoveCurrentToLast();
myListBox.ScrollIntoView(myListBox.Items.CurrentItem);


listBox.ScrollIntoView(listBox.Items [listBox.Items.Count - 1]);


Вы можете попробовать метод ListBox.ScrollIntoView(), хотя есть некоторые проблемы в некоторых случаях...

Вот пример из Tamir Khason: Автоматическая прокрутка ListBox в WPF


Несколько иной подход к представленным до сих пор.

Вы можете использовать событие ScrollViewer ScrollChanged и следить за увеличением содержимого ScrollViewer.

private void ListBox_OnLoaded(object sender, RoutedEventArgs e)
{
 var listBox = (ListBox) sender;
 var scrollViewer = FindScrollViewer(listBox);
 if (scrollViewer != null)
 {
 scrollViewer.ScrollChanged += (o, args) =>
 {
 if (args.ExtentHeightChange > 0)
 scrollViewer.ScrollToBottom();
 };
 }
}

Это позволяет избежать некоторых проблем с привязкой к изменению ListBox ItemsSource.

ScrollViewer также можно найти без предположения, что ListBox использует шаблон управления по умолчанию.

// Search for ScrollViewer, breadth-first
private static ScrollViewer FindScrollViewer(DependencyObject root)
{
 var queue = new Queue<dependencyobject>(new[] {root});
 do
 {
 var item = queue.Dequeue();
 if (item is ScrollViewer)
 return (ScrollViewer) item;
 for (var i = 0; i < VisualTreeHelper.GetChildrenCount(item); i++)
 queue.Enqueue(VisualTreeHelper.GetChild(item, i));
 } while (queue.Count > 0);
 return null;
}
</dependencyobject>

Затем присоедините это к событию ListBox Loaded:

Это может быть легко изменено как присоединенное свойство, чтобы сделать его более общей.

licensed under cc by-sa 3.0 with attribution.