I have a simple ListView with no item template and the SelectionChanged event setup:
I can tell you.
What you are experiencing here is a problem of timing. How fast do you think you can add an item to a collection? Fast - just a millisecond or two. How fast do you think it takes the ListView
to set the SelectedItem
property and raise the SelectionChanged
event? Fast - a millisecond or two. But, how fast do you think it takes the ListView
to actually render the new item on the screen and generate the container for it? A long time - like 10 to 100 milliseconds, depending on the complexity of the DataTemplate
.
I realize your test didn't set the ItemTemplate
, and I assume you did it that way assuming that it would render faster - maybe instant. But there is a default DataTemplate
in every ItemsControl
. And, even a simple DataTemplate
like the built-in one, still takes more time than it takes you to advance a single C# line.
This code will illustrate what I mean:
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var items = Enumerable.Range(1, 10)
.Select(x => new Item { FirstName = "Bob", LastName = "Smith" + x.ToString() });
var list = new ObservableCollection<Item>(items);
MyListView.ItemsSource = list;
var item = new Item { FirstName = "Jerry", LastName = "Nixon" };
list.Add(item);
await Task.Delay(1000);
MyListView.SelectedItem = item;
}
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
System.Diagnostics.Debug.Assert(e.AddedItems.Any());
var listview = sender as ListView;
var container = listview.ContainerFromItem(e.AddedItems.First());
System.Diagnostics.Debug.Assert(container != null);
var presenter = VisualTreeHelper.GetChild(container, 0);
System.Diagnostics.Debug.Assert(presenter != null);
}
Please notice the
Delay
code; this is what makes it work.
Hopefully, you simplified your question and that is why you are doing the work in code-behind and not in a view model. Fine. First, be sure and handle this type of logic in Loaded
so you can be confident that your ListView
is even available. Then again, do this in your view model.
So, I have answered your question. Why? Because of timing.
Seems to me it might all be solved with a simple view model, but then again, I only know a little bit of your situation here. Maybe there's something I am not seeing.
Best of luck!