Search code examples
xaml.net-6.0mauic#-6.0maui-windows

MAUI. ScrollView to end


I have such a problem. I have some chat with an interlocutor in Scrollview and it is dynamically updated with new messages. Somehow I had to lower the chat down all the time. I called the following method for lowering: Body.ScrollToAsync(0, Body.ContentSize.Height, true); But at the first iteration it does not lower the chat, and at the second iteration it does not lower it to the end. My question is the following: How do I always lower the chat to the end?

C# code:

    namespace MessengerMAUI;

public partial class ChatProcessor : ContentView
{
    public ChatProcessor(string Name)
    {
        InitializeComponent();
        MessagesGrid.VerticalOptions = LayoutOptions.End;
        MessagesGrid.HorizontalOptions = LayoutOptions.Fill;
        ChatName.Text = Name;
    }

    List<Bubble> Messages = new();

    public int LastMessageIndex = 0;

    private void SendButtonClicked(object sender, EventArgs e)
    {
        //DrawMessage(TextBox.Text, true);//Разкоменть это когда будешь писать соединение с сервером и закоменть то что ниже
        if (testSenderCheckBox.IsChecked)// HACK: UI Test "Кто отправляет сообщение"
        {
            DrawMessage(TextBox.Text, false);//Отправитель - собеседник
        }
        else
        {
            DrawMessage(TextBox.Text, true);//Отправитель - Я
        }
        TextBox.Text = "";//Очистка поля ввода
    }

    public async void DrawMessage(string message, bool IsMyMessage)//Adding Message like a bubble
    {
        if (message != null)
        {
            
            Messages.Add(new Bubble());
            Messages[LastMessageIndex].BubbleCreator(message, IsMyMessage);
            MessagesGrid.AddRowDefinition(new RowDefinition());
            MessagesGrid.Add(Messages[LastMessageIndex], 0, LastMessageIndex);
            Body.Content = MessagesGrid;//Update chat content

            Body.ScrollToAsync(0, Body.ContentSize.Height, true);//scrolling to end

            LastMessageIndex++;
        }
    }

    
}

XAML code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MessengerMAUI.ChatProcessor">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="84"/>
            <RowDefinition/>
            <RowDefinition Height="45"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Header" 
            HeightRequest="84" 
            Grid.Row="0">
            <Label Text="Чат" 
                FontSize="32"
                FontAttributes="Bold"
                 VerticalOptions="Center"/>
            <Label x:Name="ChatName"
                Text="Test Name" 
                VerticalOptions="Center" 
                HorizontalOptions="End" 
                FontSize="32"
                FontAttributes="Bold"/>
        </Grid>
        <ScrollView x:Name="Body"  
            Grid.Row="1">
            <Grid x:Name="MessagesGrid">
                <!--Сюда генерируются диалоги (bubbles)-->
            </Grid>
        </ScrollView>
        <Grid x:Name="Footer"  
            Grid.Row="2">
            <Grid.ColumnDefinitions >
                <ColumnDefinition/>
                <ColumnDefinition Width="105"/>
            </Grid.ColumnDefinitions>
            <Rectangle Fill="#272B2C" 
                Grid.Column="0"/>
            <Editor  x:Name="TextBox" 
                Grid.Column="0"
                VerticalTextAlignment="Center">
                <Editor.Keyboard>
                    <Keyboard x:FactoryMethod="Create">
                        <x:Arguments>
                            <KeyboardFlags>
                                CapitalizeSentence, Spellcheck, Suggestions
                            </KeyboardFlags>
                        </x:Arguments>
                    </Keyboard>
                </Editor.Keyboard>
            </Editor>
            <Button x:Name="SendButton" 
                Text="Отправить" 
                BackgroundColor="#0066DC" 
                TextColor="White" Clicked="SendButtonClicked" 
                Grid.Column="2"/>
            <CheckBox x:Name="testSenderCheckBox"/> <!--Удали это, когда сделаешь общение с сервером-->
        </Grid>
    </Grid>
</ContentView>

Solution

  • You can try to scroll to the last child of your MessagesGrid like below:

    var lastChild = MessagesGrid.Children.LastOrDefault(); 
    if (lastChild != null)
    {
        //await Body.ScrollToAsync(0, MessagesGrid.Height, true);
          await Body.ScrollToAsync(MessagesGrid, ScrollToPosition.End, true);
    }