У меня есть ListView
, привязанный к списку на ViewModel
. Моя модель довольно проста:
public class Model : RealmObject
{
public string Name { get; set; }
}
В представлении мало что происходит, но я добавил контекстное действие к ячейкам, привязанным к DeleteCommand
:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Book.Views.MyPage"
x:Name="page">
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding Models}"
SelectionMode="Single"
CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}">
<TextCell.ContextActions>
<MenuItem Command="{Binding Path=BindingContext.DeleteCommand, Source={x:Reference page}}"
CommandParameter="{Binding .}"
Text="Delete" IsDestructive="True" />
</TextCell.ContextActions>
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Затем у нас есть ViewModel
public class MyViewModel : BaseViewModel
{
readonly Realm realm;
public ICommand DeleteCommand { get; private set; }
public IEnumerable<Model> Models { get; set; }
public ContactsListViewModel()
{
realm = Realm.GetInstance();
AddElements();
Models = realm.All<Model>();
DeleteCommand = new Command<Model>(Delete);
}
void AddElements() //For testing
{
for (int i = 0; i < 5; i++)
{
realm.Write(() =>
{
var c = new Model()
{
Name = $"Name{i}"
};
realm.Add(c);
});
}
}
void Delete(Model model)
{
realm.Write(() =>
{
realm.Remove(model);
});
}
}
Моя проблема в том, что я получаю ArgumentOutOfRangeException
, как только пытаюсь что-то удалить. Трассировка стека выглядит следующим образом:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: index
at Xamarin.Forms.ListProxy.get_Item (System.Int32 index) [0x0000b] in D:\a\1\s\Xamarin.Forms.Core\ListProxy.cs:129
at Xamarin.Forms.ListProxy.System.Collections.IList.get_Item (System.Int32 index) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\ListProxy.cs:443
at Xamarin.Forms.Platform.Android.ListViewAdapter.GetDataTemplateForPath (System.Int32 indexPath) [0x00007] in D:\a\1\s\Xamarin.Forms.Platform.Android\Renderers\ListViewAdapter.cs:367
at Xamarin.Forms.Platform.Android.ListViewAdapter.GetPrototypicalCell (System.Int32 indexPath) [0x00012] in D:\a\1\s\Xamarin.Forms.Platform.Android\Renderers\ListViewAdapter.cs:391
at Xamarin.Forms.Platform.Android.ListViewAdapter.IsEnabled (System.Int32 position) [0x00023] in D:\a\1\s\Xamarin.Forms.Platform.Android\Renderers\ListViewAdapter.cs:427
at Android.Widget.BaseAdapter.n_IsEnabled_I (System.IntPtr jnienv, System.IntPtr native__this, System.Int32 position) [0x00008] in <55654ebe9f2a48e6bade2862bb243f94>:0
at at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.72(intptr,intptr,int)
Это происходит только на Android, и этого не происходит, если я удалю CachingStrategy="RecycleElement"
ИЛИ если я заключу содержимое Delete
в Device.BeginInvokeOnMainThread
. Последнее не имеет для меня особого смысла, поскольку Delete
уже вызывается в потоке пользовательского интерфейса.
Учитывая, что происходит, я полагаю, что это может быть состояние гонки, но, возможно, кто-то может избавиться немного света на то, почему это происходит?