In my application, I have a ListBox
with items. The application is written in WPF.
How can I scroll automatically to the last added item? I want the
You could try ListBox.ScrollIntoView() method, although there are some problems in some cases...
Here is an example from Tamir Khason: Auto scroll ListBox in WPF
The easiest way to do this:
if (VisualTreeHelper.GetChildrenCount(listView) > 0)
{
Border border = (Border)VisualTreeHelper.GetChild(listView, 0);
ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
scrollViewer.ScrollToBottom();
}
It is always working for ListView and ListBox controls. Attach this code to the listView.Items.SourceCollection.CollectionChanged
event and you have fully automatic auto-scrolling behaviour.
listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);
A slightly different approach to those presented so far.
You could use the ScrollViewer
ScrollChanged
event and watch for the content of the ScrollViewer
getting larger.
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();
};
}
}
This avoids some issues with the binding to the ListBox
ItemsSource
changing.
The ScrollViewer
can also be found without making the assumption that the ListBox
is using the default control template.
// 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;
}
Then attach this to the ListBox
Loaded
event:
<ListBox Loaded="ListBox_OnLoaded" />
This could be easily modified to be an attached property, to make it more general purpose.
For me, the simplest working way was this: (without Binding)
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]);
}));
}
Don't need to create classes or change the xaml, just write the messages with this method and it scroll automatically.
Calling just
myLv.Items.Add(ls);
myLv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
for exemple, don't work for me.
Try this:
lstBox.SelectedIndex = lstBox.Items.Count -1;
lstBox.ScrollIntoView(lstBox.SelectedItem) ;
In your MainWindow, this will select and focus on last item on the list!