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>
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);
}