asynchronous - 在 Task.Delay() 中将元素添加到 XAML 页面
问题描述
我正在构建一个聊天机器人应用程序,其中包含用于传入和传出消息的聊天气泡。对于传入的消息,我给它一个Task.Delay()
,现在我想ActivityIndicator
在消息弹出之前给它一个(即我想在消息被延迟时显示活动指示器)。我已将活动指示器添加到传入消息控件的 XAML;
传入消息项控件
<ViewCell
x:Class="BluePillApp.Controls.IncomingMessageItemControl"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pancake="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
mc:Ignorable="d">
<Grid x:Name="Gridoo">
<pancake:PancakeView
Margin="10,10,80,10"
Padding="15"
BackgroundColor="#53ffc6"
CornerRadius="20,20,0,20"
HasShadow="False"
HorizontalOptions="StartAndExpand">
<Label
FontSize="Medium"
Text="{Binding Text}"
TextColor="#1a1a1a" />
</pancake:PancakeView>
<ActivityIndicator IsRunning="True" IsVisible="True" />
</Grid>
</ViewCell>
问题是,在 ChatbotMessagingPage 中,按下发送按钮,然后在收到回复/传入消息之前发送传出消息,我已经在 MVVM 中这样做了;
ChatbotMessagingPageViewModel
//This gets the chatbots response for each message
chatbot.MainUser.ResponseReceived += async (sender, args) =>
{
await Task.Delay(1500);
Messages.Add(new ChatMessageModel() { Text = args.Response.Text, User = App.ChatBot });
};
}
#region CLASS METHODS
/// <summary>
/// This function sends a message
/// </summary>
public void Send()
{
if (!string.IsNullOrEmpty(TextToSend))
{
var msgModel = new ChatMessageModel() { Text = TextToSend, User = App.User };
//This adds a new message to the messages collection
Messages.Add(msgModel);
var result = chatbot.Evaluate(TextToSend);
result.Invoke();
//Removes the text in the Entry after message is sent
TextToSend = string.Empty;
}
}
每次我按下发送按钮时,ActivityIndicator 都会与 IncomingMessage 一起出现,我希望 ActivityIndicator 先出现,而 IncomingMessage 会被延迟。
解决方案
我猜那个视图单元格是消息气泡。
当你这样做时:
Messages.Add(new ChatMessageModel() { Text = args.Response.Text, User = App.ChatBot });
您的集合已更新,您的 ListView 或任何持有这些 ViewCelss 的东西也会更新。TheActivityIndicator
是 the 的一部分,ViewCell
因此它与消息同时出现。
[选项 1] 使用附加标志
您可以做的是创建一个标志IsBusy
或IsDelay
其他东西并将 ActivityIndicator 和 Label 的可见性绑定到它:
<Grid x:Name="Gridoo">
<pancake:PancakeView
Margin="10,10,80,10"
Padding="15"
BackgroundColor="#53ffc6"
CornerRadius="20,20,0,20"
HasShadow="False"
HorizontalOptions="StartAndExpand">
<Label
FontSize="Medium"
Text="{Binding Text}"
TextColor="#1a1a1a"
IsVisible="{Binding IsBusy, Converter={Helpers:InverseBoolConverter}}""> />
</pancake:PancakeView>
<ActivityIndicator x:Name="activityIndicator" IsRunning="True" IsVisible="{Binding IsBusy}" />
</Grid>
请注意,我使用 aIValueConverter
来否定标签的值。如果您不熟悉它,请检查此
剩下的就是在你的ViewModel
:
IsBusy = true; // this will make the activity indicator visible, but not the Label
// Also note that you first need to add the message
Messages.Add(new ChatMessageModel() { Text = args.Response.Text, User = App.ChatBot });
await Task.Delay(1500);
IsBusy = false; // this will hige the activity indicator visible, and make Label visible
所以基本上逻辑如下:
- 您将消息添加到聊天中,但实际文本是隐藏的,而另一方面,活动指示器是可见的。
- 你应用延迟
- 延迟结束,您更改两个视图的可见性。
请注意,在我的示例中,我没有声明该标志的位置,因为我不确定其余代码的外观。它可以添加到 ChatMessageModel 中,或者ChatMessageViewModel
因为您需要为每条消息添加一个标志。
[选项 2] IncomingMessageItemControl.xaml.cs
更好的解决方案可能是在控件后面的代码中处理它。问题是一样的,活动指示器和标签同时出现。
要解决此问题,您可以将延迟移入IncomingMessageItemControl.xaml.cs
. 首先,您需要同时添加x:Name
活动指示器和标签。
然后你可以这样做:
private async Task ChangeVisibilityAsync()
{
Label.IsVisibe= false;
ActivityIndicator.IsVisible = true;
await Task.Delay(1500);
Label.IsVisibe = true;
ActivityIndicator.IsVisible = false;
}
推荐阅读
- scala - SameSite=None 正在成为另一个 cookie
- javascript - 在画布中绘制旋转圆角矩形而不使用 canvas.rotate()
- gradle - Gradle 通过命令行修改 build.gradle 文件
- c# - 在列表中查找重复键并返回具有最新日期的对象
- reactjs - ReactJS 测试 - 检查组件是否在 componentDidMount 中的异步调用后渲染
- c - TCP套接字,发送文件,客户端服务器,服务器不保存整个文件,C语言
- delphi - 如何在 EMS Rad 服务器中提供多个版本的资源 BPL 文件
- scala - Scala中3种类型之间的协方差
- java - 如何在应用关闭时自动关闭 WiFi
- batch-file - 由于从挂起的 VPN 连接断开而不中断工作流而刷新网络驱动器的方法