WPF ListBox Scrollen, um automatisch zu beenden


Answers

Versuche dies:

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

In meiner Anwendung habe ich eine ListBox mit Elementen. Die Anwendung ist in WPF geschrieben.

Wie kann ich automatisch zum zuletzt hinzugefügten Element blättern? Ich möchte, dass der ScrollViewer an das Ende der Liste verschoben wird, wenn ein neues Element hinzugefügt wurde.

Gibt es ein Event wie ItemsChanged ? (Ich möchte das SelectionChanged Ereignis nicht verwenden)




listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); Sie, dass listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); funktioniert nur, wenn Sie keine doppelten Einträge haben. Wenn Sie Objekte mit demselben Inhalt haben, scrollt es zum ersten gefundenen Objekt.

Hier ist die Lösung, die ich gefunden habe:

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);



Die beste Lösung besteht darin, das ItemCollection-Objekt im ListBox-Steuerelement zu verwenden. Diese Auflistung wurde speziell für Inhaltsbetrachter entwickelt. Es hat eine vordefinierte Methode, um das letzte Element auszuwählen und eine Cursorpositionsreferenz beizubehalten ....

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



Der einfachste Weg, dies zu tun:

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

Es funktioniert immer für ListView- und ListBox-Steuerelemente. listView.Items.SourceCollection.CollectionChanged Sie diesen Code dem listView.Items.SourceCollection.CollectionChanged Ereignis hinzu, und Sie verfügen über ein vollständig automatisches automatisches Bildlaufverhalten.




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




Ein etwas anderer Ansatz als bisher.

Sie können das ScrollViewer Ereignis ScrollViewer ScrollChanged und ScrollViewer ScrollChanged , dass der Inhalt des ScrollViewer größer wird.

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();
        };
    }
}

Dies vermeidet einige Probleme mit der Änderung der Bindung an die ListBox ItemsSource .

Der ScrollViewer kann auch gefunden werden, ohne dass davon ListBox wird, dass die ListBox die Standardsteuervorlage verwendet.

// 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 das dann dem ListBox Loaded Ereignis hinzu:

<ListBox Loaded="ListBox_OnLoaded" />

Dies könnte leicht modifiziert werden, um eine angefügte Eigenschaft zu sein, um es allgemeiner zu machen.