I use a ListView
to show a list of errors as they occur in my application. It behaves and looks exactly like the Error List in Visual Studio. I want to add auto-scrolling when the last error item is selected (like how Visual Studio's Log Window auto-scrolls when you place the caret at the end).
The list of errors is in an ObservableCollection
, which is passed to the ListView.ItemsSource
like this:
public ObservableCollection<ErrorListItem> Items;
...
MyListView.ItemsSource = _Items;
I tried performing the auto-scroll in the _Items_CollectionChanged
event handler, but because this is the event on the ItemsSource
and not on the actual ListViewItems
, it's a pain to figure out if the last item is selected, select the new row, etc. It's especially hard since it seems the ListViewItems
are not created instantly. I managed to make it auto-scroll by delaying the call to set the last item selected like this:
void _Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// determine the last item to select from 'e'
...
_ItemPendingToBeScrolled = newItemToSelect;
ListView.SelectedItem = newItemToSelect;
Dispatcher.BeginInvoke(DispatcherPriority.Background,
(ThreadStart)delegate
{
if (_ItemPendingToBeScrolled != null)
{
ListView.ScrollIntoView(_ItemPendingToBeScrolled);
ItemPendingToBeScrolled = null;
}
})
}
But that's obviously not the right way to do it. Also, I want things to keep working if the list is filtered (not checking the last item in my source, but the last ListViewItem
in the ListView
).
Is there a way to listen to events when a ListViewItem
gets added to the ListView
following an addition to the bound collection? That would be the ideal event to capture in order to properly do my auto-scrolling. Or is there another technique I could use?