Question

I'm creating an app similar to the stock Messaging. But i'm very new to wp8 development and also to c# and .net

I'm using the Long List Selector to display messages. Messages are loaded on NavigatedTo event of the page. the handler is async as it is loading the data from a webservice, when there are 0 stored in local db, then it saves them in local database.

I would like to scroll to the last message after the data is loaded.

the page OnNavigated to

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    string contactId = "";
    if (NavigationContext.QueryString.TryGetValue("contactId", out contactId))
    {
        await App.MessagesViewModel.LoadData();

        DataContext = App.MessagesViewModel;

        //scroll to last message, but it's apparently to soon
        var lastMessage = App.MessagesViewModel.Messages.LastOrDefault();
        llsMessages.ScrollTo(lastMessage);
    }
}

but this throws an exception System.ArgumentException: The provided item doesn't exist in the collection. So i figured the list hasn't yet changed.

So i tried different events of LongListSelector that would indicate that it has already added the data from the view model. After a while of experimetnation i came up with this

private void llsMessages_SizeChanged(object sender, SizeChangedEventArgs e)
{
    var lastMessage = App.MessagesViewModel.Messages.LastOrDefault();
    if (lastMessage != null)
    {
        llsMessages.ScrollTo(lastMessage);
    }
}

but this works only when the messages are loaded from the database. When loading from webservice the last message is null.

So after load i'm on the first message at top, then i navigate away from the page, then come back, the list scrolls to bottom. i would like to eliminate this, but i have no idea how.

is there any way how to accomplish this?

Was it helpful?

Solution

Maybe this will work:

private async Task DoAndScroll()
{
   await App.MessagesViewModel.LoadData();
   var lastMessage = App.MessagesViewModel.Messages.LastOrDefault();
   llsMessages.ScrollTo(lastMessage);
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   string contactId = "";
   if (NavigationContext.QueryString.TryGetValue("contactId", out contactId))
   {
      DataContext = App.MessagesViewModel;  
      DoAndScroll();     
   }
}

OTHER TIPS

Try the ItemRealized event of the longlistselector. Check whether the currently processed item in the selector is the last item of your datacontext and if it is so, then scroll to that item. Below code worked for me.

private void longlist_ItemRealized(object sender, ItemRealizationEventArgs e)
    {
        Search.BindSearch search = e.Container.Content as Search.BindSearch;
        if (search != null)
        {
            int offset = 0;

            if (OCollectionBindSearch.Count - OCollectionBindSearch.IndexOf(search) <= offset)
            {
                longlist.ScrollTo(search);
            }                
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top