简体   繁体   English

ScrollToAsync .Net Maui 仅在我第二次按下按钮时有效

[英]ScrollToAsync .Net Maui only Works the second time I press the button

I am working currently on a chat program and when I display the chat history of two people, I want to scroll to the last message/end of the Vertical Stack Layout --> I do it with the .ScrollToAsync Function.我目前正在开发一个聊天程序,当我显示两个人的聊天历史记录时,我想滚动到垂直堆栈布局的最后一条消息/结尾 --> 我使用 .ScrollToAsync 函数来完成。

If I click one of the User Buttons, then the History gets loaded from a local storing method.如果我单击其中一个用户按钮,则会从本地存储方法加载历史记录。 After that the program creates a label for every message and adds it to the scrollable vertical stack layout.之后,程序为每条消息创建一个标签,并将其添加到可滚动的垂直堆栈布局中。 After that it should scroll to the end of the vertical stack layout.之后,它应该滚动到垂直堆栈布局的末尾。 With the following code snippet:使用以下代码片段:

await Scroller.ScrollToAsync(TextField, ScrollToPosition.End, false);  

The complete method is here:完整的方法在这里:

private async void OnCounterClicked(object sender, EventArgs e)
    {
        if (m_currentLabels != null)
        {
            foreach(Label label in m_currentLabels)
            {
                TextField.Remove(label);
            }
        }

        m_currentLabels = new List<Label>();
        Button button =(Button) sender;
        string str = button.Text;
        Guid userId = m_userDictionary[str];
        List<Guid> guids = new List<Guid>();
        guids.Add(userId);
        m_currChannelPartners = guids;

        List<MessageModel> localMessages = m_eChatBusiness.GetMessages(MessageModel.Yourself.ID, guids);
        foreach(MessageModel message in localMessages)
        {
            Label messageLabel = new Label();
            messageLabel.Text = $"{message.Created} {message.Message} | {GetStatus(message)}";
            messageLabel.TextColor = Color.Parse("White");
            messageLabel.HorizontalTextAlignment = message.Position == "End"? TextAlignment.End:TextAlignment.Start;
            m_currentLabels.Add(messageLabel);
            TextField.Add(messageLabel);
        }

        await Scroller.ScrollToAsync(TextField, ScrollToPosition.End, false); 
    }

Scroller is the ScrollView and the TextField is the vertical stack layout. Scroller 是 ScrollView,TextField 是垂直堆栈布局。

The weird thing is: It works, when I click the button a second time.奇怪的是:当我第二次单击该按钮时,它起作用了。 I tried to guess, but since I call the asynchronous function at the end of the method, the TextField should be fully initialized or not?我试图猜测,但是由于我在方法的末尾调用了异步函数,所以 TextField 应该完全初始化还是没有?

I hope you can help me!我希望你能帮帮我!

I found a workaround for that problem, with the help of my chief:在我的主管的帮助下,我找到了解决该问题的方法:

You have to enable a timer object, which gets a function, which is calling the desired function Scroller.ScrollToAsync(TextField, ScrollToPosition.End, false) inside the mainThread (because otherwise an exception is thrown).您必须启用一个计时器对象,该对象获取一个函数,该函数在 mainThread 内调用所需的函数 Scroller.ScrollToAsync(TextField, ScrollToPosition.End, false) (否则会引发异常)。 Important is the Infinite Timeout, so that the action only executes one time.重要的是无限超时,以便操作只执行一次。

Here is the code, if somebody has the same Problem:这是代码,如果有人有同样的问题:

Timer timer = new Timer((object obj) => {
            MainThread.BeginInvokeOnMainThread(() => Scroller.ScrollToAsync(TextField, ScrollToPosition.End, false));
        }, null, 100, Timeout.Infinite);

The 100 are the time how long the timer objects waits, before execution. 100 是计时器对象在执行前等待的时间。 The really good thing now is, that the UI is not blocked anymore!现在真正的好处是,用户界面不再被阻塞!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM