如何在 Xamarin 中的 CollectionChange 事件中获取滚动当前位置?

How to get scroll current position upon CollectionChange event in Xamarin?

我有一个 Xamarin 聊天应用程序,当我收到新消息时,它会滚动到最近收到的消息。 如果我看到必须的最新消息,我希望发生这种情况,否则如果用户滚动到旧消息并且新消息到达,我希望显示一个按钮(就像在团队中一样)说 "new" 如果你点击您滚动到最近的消息。

这里的问题是,为了做到这一点,我现在必须能够知道用户在屏幕上看到的消息,至少知道底部屏幕消息或只是滚动当前位置!在知道我可以自己完成剩下的事情之后。

这是我的 OnAppearing 方法:

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (viewModel.Messages.Count == 0)
        {
            viewModel.LoadItemsCommand.Execute(null);
        }

        viewModel.Messages.CollectionChanged += (sender, e) =>
        {
            //GET SCROLL CURRENT POSITION HERE!
            var target = viewModel.Messages[viewModel.Messages.Count - 1];

            ItemsListView.ScrollTo(target, ScrollToPosition.End, false);
        };            
    }

谢谢大家!

终于找到了获取滚动条当前位置的方法!!

基本上,如果你像我一样有一个 ListView,一旦它默认包含一个滚动条,你就可以这样做:

        YourListViewName.Scrolled += (sender, e) =>
        {
            var scrollCurrentVerticalPosition = e.ScrollY;                
        };

对于我的情况,我不得不这样做,而不是在 CollectionChanged 事件中进行调用:

创建私有变量:

private bool scrollPositionEnd = true;

在 OnAppearing 方法中:

protected override void OnAppearing()
{
    base.OnAppearing();

    if (viewModel.Messages.Count == 0)
    {
        viewModel.LoadItemsCommand.Execute(null);
    }

    viewModel.Messages.CollectionChanged += (sender, e) =>
    {            
        if (scrollPositionEnd == true)
        {
            ScrollToEnd();
        }
        else if (GetLastMessage().UserId != UserId) //so it wont trigger on your own messages
        {
            NewMessagesButton.IsVisible = true;
        }
    };    

    ItemsListView.Scrolled += (sender, e) =>
    {
        if (e.ScrollY == 0) //when scroll is in bottom ScrollY value is 0 
        {
            scrollPositionEnd = true;

            //if you manually scroll down until the new message
            NewMessagesButton.IsVisible = false;
        }
        else
        {
             scrollPositionEnd = false;
        }
    };
 }

辅助方法:

    //If you click the button event
    private void ButtonScrollClick(object sender, EventArgs e)
    {
        ScrollToEnd();
    }

    private void ScrollToEnd()
    {
        NewMessagesButtonFrame.IsVisible = false;
        Message target = GetLastMessage();
        ItemsListView.ScrollTo(target, ScrollToPosition.End, false);
    }

    private Message GetLastMessage()
    {
        return viewModel.Messages[viewModel.Messages.Count - 1];
    }

谢谢大家的提示,如果您喜欢我的回答,请免费投票 :)