Xamarin.Forms 分组列表视图无法在 Android 中添加新组
Xamarin.Forms Grouped List View fails on adding new groups in Android
我正在使用 Xamarin.Forms 为 Android 和 windows Phone.
开发移动应用程序
我有一个消息列表视图,它绑定到组的 ObservableCollection。该列表按天对消息进行分组,然后按时间顺序显示消息 - 非常标准的东西。
我现在遇到的问题是,在 Android 中 - 使用 Add 函数将新组添加到 ObservableCollection 会导致触发未处理的异常。
04-22 13:13:32.404 D/Mono (19971): DllImport attempting to load:
'/system/lib/liblog.so'. 04-22 13:13:32.404 D/Mono (19971):
DllImport loaded library '/system/lib/liblog.so'. 04-22 13:13:32.404
D/Mono (19971): DllImport searching in: '/system/lib/liblog.so'
('/system/lib/liblog.so'). 04-22 13:13:32.404 D/Mono (19971):
Searching for '__android_log_print'. 04-22 13:13:32.414 D/Mono
(19971): Probing '__android_log_print'. 04-22 13:13:32.414 D/Mono
(19971): Found as '__android_log_print'. 04-22 13:13:32.434
I/MonoDroid(19971): UNHANDLED EXCEPTION: An unhandled exception
occured.
04-22 13:13:32.444 I/MonoDroid(19971):
System.ArgumentOutOfRangeException: Argument is out of range. 04-22
13:13:32.444 I/MonoDroid(19971): Parameter name: index 04-22
13:13:32.444 I/MonoDroid(19971): at
System.Collections.Generic.List1<object>.get_Item (int) <0x0007c>
04-22 13:13:32.444 I/MonoDroid(19971): at
Cadenza.Collections.OrderedDictionary
2,
Xamarin.Forms.Cell>>.get_Item (int) <0x00063>
这在 Windows 中不是问题。
我可以通过使用 AddRange 函数来解决这个问题,只需先将我要添加的项目添加到另一个 "temporary list",然后将该临时列表添加到main Collection - 这解决了它,但似乎有点 hack。
另一种方法是在主线程上执行此操作:
Device.BeginInvokeOnMainThread(() =>
{
// using of add function in this manner works.
});
有没有人遇到过类似的问题,你找到解决办法了吗?
谢谢,
您正在从不同的线程执行 Add
操作。 ObservableCollection
不是线程安全的。
您可以通过创建自定义线程安全 ObservableCollection
来解决这个问题(例如,最简单的使用 lock
语句甚至 Device.BeginInvokeOnMainThread
调用,它将对操作进行排队一个主线程)。
您也可以使用 BindingBase.EnableCollectionSynchronization
进行集合同步。 https://forums.xamarin.com/discussion/19114/invalid-number-of-rows-in-section
基于 @Daniel Luberda's , I too recommend using BindingBase.EnableCollectionSynchronization
,因为 ObservableCollection
不是线程安全的。
我在这里整理了一篇关于该主题的博客 post:https://www.codetraveler.io/2019/08/27/using-observablecollection-in-a-multi-threaded-xamarin-forms-application/
BindingBase.EnableCollectionSynchronization 例子
注意:确保在调用 EnableCollectionSynchronization
之前初始化 ObservableCollection
class MyViewModel
{
public MyViewModel()
{
MyCollection = new ObservableCollection<MyModel>();
Xamarin.Forms.BindingBase.EnableCollectionSynchronization(MyCollection, null, ObservableCollectionCallback);
}
public ObservableCollection<MyModel> MyCollection { get; }
void ObservableCollectionCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess)
{
lock (collection)
{
accessMethod?.Invoke();
}
}
}
Task loadLineItems = Task.Run( () =>
{
foreach (listEntity item in newList)
{
this.ObservalCollectionFromVM.Add(item);
}
});
loadLineItems.Wait();
或
Task loadLineItems = Task.Run(async () =>
{
var list == await DependencyService.Get<IEntityService>().GetEntityListAsync();
foreach (Entity item in list)
{
this.ObservalCollectionFromVM.Add(item);
}
});
loadLineItems.Wait();
我正在使用 Xamarin.Forms 为 Android 和 windows Phone.
开发移动应用程序我有一个消息列表视图,它绑定到组的 ObservableCollection。该列表按天对消息进行分组,然后按时间顺序显示消息 - 非常标准的东西。
我现在遇到的问题是,在 Android 中 - 使用 Add 函数将新组添加到 ObservableCollection 会导致触发未处理的异常。
04-22 13:13:32.404 D/Mono (19971): DllImport attempting to load: '/system/lib/liblog.so'. 04-22 13:13:32.404 D/Mono (19971): DllImport loaded library '/system/lib/liblog.so'. 04-22 13:13:32.404 D/Mono (19971): DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so'). 04-22 13:13:32.404 D/Mono (19971): Searching for '__android_log_print'. 04-22 13:13:32.414 D/Mono
(19971): Probing '__android_log_print'. 04-22 13:13:32.414 D/Mono
(19971): Found as '__android_log_print'. 04-22 13:13:32.434 I/MonoDroid(19971): UNHANDLED EXCEPTION: An unhandled exception occured.04-22 13:13:32.444 I/MonoDroid(19971): System.ArgumentOutOfRangeException: Argument is out of range. 04-22 13:13:32.444 I/MonoDroid(19971): Parameter name: index 04-22 13:13:32.444 I/MonoDroid(19971): at System.Collections.Generic.List
1<object>.get_Item (int) <0x0007c> 04-22 13:13:32.444 I/MonoDroid(19971): at Cadenza.Collections.OrderedDictionary
2, Xamarin.Forms.Cell>>.get_Item (int) <0x00063>
这在 Windows 中不是问题。
我可以通过使用 AddRange 函数来解决这个问题,只需先将我要添加的项目添加到另一个 "temporary list",然后将该临时列表添加到main Collection - 这解决了它,但似乎有点 hack。
另一种方法是在主线程上执行此操作:
Device.BeginInvokeOnMainThread(() =>
{
// using of add function in this manner works.
});
有没有人遇到过类似的问题,你找到解决办法了吗?
谢谢,
您正在从不同的线程执行 Add
操作。 ObservableCollection
不是线程安全的。
您可以通过创建自定义线程安全
ObservableCollection
来解决这个问题(例如,最简单的使用lock
语句甚至Device.BeginInvokeOnMainThread
调用,它将对操作进行排队一个主线程)。您也可以使用
BindingBase.EnableCollectionSynchronization
进行集合同步。 https://forums.xamarin.com/discussion/19114/invalid-number-of-rows-in-section
基于 @Daniel Luberda's BindingBase.EnableCollectionSynchronization
,因为 ObservableCollection
不是线程安全的。
我在这里整理了一篇关于该主题的博客 post:https://www.codetraveler.io/2019/08/27/using-observablecollection-in-a-multi-threaded-xamarin-forms-application/
BindingBase.EnableCollectionSynchronization 例子
注意:确保在调用 EnableCollectionSynchronization
class MyViewModel
{
public MyViewModel()
{
MyCollection = new ObservableCollection<MyModel>();
Xamarin.Forms.BindingBase.EnableCollectionSynchronization(MyCollection, null, ObservableCollectionCallback);
}
public ObservableCollection<MyModel> MyCollection { get; }
void ObservableCollectionCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess)
{
lock (collection)
{
accessMethod?.Invoke();
}
}
}
Task loadLineItems = Task.Run( () =>
{
foreach (listEntity item in newList)
{
this.ObservalCollectionFromVM.Add(item);
}
});
loadLineItems.Wait();
或
Task loadLineItems = Task.Run(async () =>
{
var list == await DependencyService.Get<IEntityService>().GetEntityListAsync();
foreach (Entity item in list)
{
this.ObservalCollectionFromVM.Add(item);
}
});
loadLineItems.Wait();