Nancy Kanwar
Nancy Kanwar

Reputation: 157

Scrolling to end position in a list-view

I have a class "ChatListView" which is inherited from Listview.

public  class ChatListView:ListView
{
}

and have made a list programatically using ChatListView in Cs :

 messageList = new ChatListView();
            messageList.HasUnevenRows = true;
            messageList.VerticalOptions = LayoutOptions.FillAndExpand;
            messageList.SetBinding(ChatListView.ItemsSourceProperty, new Binding("Messages"));
            messageList.ItemTemplate = new DataTemplate(CreateMessageCell);

I have binded this to a viewmodel where I am getting "Messages"

 Messages = new ObservableCollection<ChatMessageViewModel>(TotalMessages.Skip(TotalMessages.Count - App.PagingCount));

I need to scroll the list to its end position .For which I have written code as follow:

 ViewModel.Messages.CollectionChanged += (s, ex) =>
        {

            Device.BeginInvokeOnMainThread(() =>
            {
                if (ViewModel.Messages.Any())
                {
                    messageList.ScrollTo(ViewModel.Messages.LastOrDefault(), ScrollToPosition.End, false);

                }
            });
        };

But This just doesn't work for me. I feel there would be a problem in List call or List name. Any guidance or help can help me find what is wrong with my approach.

Upvotes: 1

Views: 199

Answers (3)

Narendra Sharma
Narendra Sharma

Reputation: 682

Try this code.. this worked for me.

if (Device.RuntimePlatform == Device.Android)
                {
                    messageList.ScrollTo(ViewModel.Messages.LastOrDefault(), ScrollToPosition.End, false);
                }
                else if (Device.RuntimePlatform == Device.iOS)
                {
                    messageList.ScrollTo(ViewModel.Messages.LastOrDefault(), ScrollToPosition.End, true);
                }

Upvotes: 0

G.Mich
G.Mich

Reputation: 1666

Try to change ScrollToPosition.End to ScrollToPosition.MakeVisible

Upvotes: 1

Cheesebaron
Cheesebaron

Reputation: 24460

Instead of swapping out the Messages instance every time you get new messages, you should simply add to it. Otherwise your entire ListView will refresh and the CollectionChanged event won't fire, because it is an entirely new instance.

So when you receive messages do:

Messages.Add(newMessage);

Then the CollectionChanged event will fire the Added event:

ViewModel.Messages.CollectionChanged += OnCollectionChanged;

private void OnCollectionChanged(object sender, CollectionChangeEventArgs args)
{
    if (args.Action == CollectionChangeAction.Add) // items were added
    {
        messageList.ScrollTo(ViewModel.Messages.LastOrDefault(), ScrollToPosition.End, false);
    }
}

Make sure to instantiate Messages in your constructor or as part of the property declaration.

public ObservableCollection<ChatMessageViewModel> Messages { get; } = new ObservableCollection<ChatMessageViewModel>();

Upvotes: 2

Related Questions