在我的Xamarin Forms应用程序中,我有一个聊天页面,其中包含列出聊天项目的ListView。
这是聊天页面viewmodel:
public class IndexViewModel : BaseViewModel
{
public ObservableCollection<Model.Chat> Items { get; set; }
public Command LoadItemsCommand { get; set; }
public IndexViewModel()
{
Items = new ObservableCollection<Model.Chat>();
LoadItemsCommand = new Command( () => ReadTheList());
MessagingCenter.Subscribe<RootPage, Model.Chat>(this, "NewMessage", (obj, item) =>
{
var chat = item as Model.Chat; // Inspecting this as a local variable during debugging looks fine
// when an item is added like this the app freezes
Items.Add(chat);
});
}
void ReadTheList()
{
var items = repo.ChatList();
Items.Clear();
foreach (var item in items)
{
// when an item is added like this, all is fine
Items.Add(item);
}
}
}
每当有新的聊天消息到达时,我想向下滚动到最后一条消息(新添加的消息)。所以我在我的视图中添加了这个委托:
viewModel.Items.CollectionChanged += (sender, e) =>
{
if (viewModel.Items.Count == 0) return;
Debug.WriteLine("I can always see this when a chat item is added to the collection");
chatList.ScrollTo(viewModel.Items.Last(), ScrollToPosition.End, false); // this is where the freeze happens
};
当我从本地存储添加项目列表并且列表滚动到底部时,委托的最后一行正常工作,但是当通过MessagingCenter订阅添加新接收的聊天项目时,它会冻结我的应用程序。当新邮件到达并且页面处于打开状态并且我没有与页面上的任何内容进行交互时,这种情况会一直发生。
任何人都可以帮我调试吗?
答案 0 :(得分:2)
当处理像处理列表搜索这样繁重的后台进程时,请在一个线程上进行处理以避免此类问题。
将CllectionChanged
处理程序更改为:
viewModel.Items.CollectionChanged += (sender, e) =>
{
if (viewModel.Items.Count == 0) return;
Debug.WriteLine("I can always see this when a chat item is added to the collection");
Device.BeginInvokeOnMainThread(() =>
chatList.ScrollTo(viewModel.Items.Last(), ScrollToPosition.End, false));
};