Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

Попробуй это:

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

В вашем MainWindow это выберет и сфокусируется на последнем элементе в списке!

Ответ 2

Имейте в виду, что 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);

Ответ 3

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

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, и у вас есть полностью автоматическое поведение автоматической прокрутки.

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

Вы можете использовать событие 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;
}

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

<ListBox Loaded="ListBox_OnLoaded" />

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

Ответ 8

Для меня самый простой способ работы был такой: (без привязки)

 private void WriteMessage(string message, Brush color, ListView lv)
        {

            Dispatcher.BeginInvoke(new Action(delegate
            {
                ListViewItem ls = new ListViewItem
                {
                    Foreground = color,
                    Content = message
                };
                lv.Items.Add(ls);
                lv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
            }));
        }

Не нужно создавать классы или изменять xaml, просто напишите сообщения с помощью этого метода, и он автоматически прокрутится.

Звонить просто

myLv.Items.Add(ls);
myLv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);

Например, не работать на меня.