2016-03-22 23:02:25 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Xamarin.Forms.CustomAttributes;
|
2016-04-26 18:20:55 +03:00
|
|
|
|
using Xamarin.Forms.Internals;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
2018-06-15 14:34:47 +03:00
|
|
|
|
#if UITEST
|
|
|
|
|
using Xamarin.UITest;
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
using Xamarin.Forms.Core.UITests;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace Xamarin.Forms.Controls.Issues
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2018-06-15 14:34:47 +03:00
|
|
|
|
[Preserve(AllMembers = true)]
|
|
|
|
|
[Issue(IssueTracker.Github, 1875, "NSRangeException adding items through ItemAppearing", PlatformAffected.iOS)]
|
|
|
|
|
#if UITEST
|
|
|
|
|
[NUnit.Framework.Category(UITestCategories.ListView)]
|
|
|
|
|
#endif
|
2016-03-22 23:02:25 +03:00
|
|
|
|
public class Issue1875
|
2018-06-15 14:34:47 +03:00
|
|
|
|
: TestContentPage
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2018-06-15 14:34:47 +03:00
|
|
|
|
MainViewModel _viewModel;
|
|
|
|
|
int _start = 0;
|
|
|
|
|
const int NumberOfRecords = 15;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected override void Init()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
Button loadData = new Button { Text = "Load", HorizontalOptions = LayoutOptions.FillAndExpand };
|
2018-06-15 14:34:47 +03:00
|
|
|
|
ListView mainList = new ListView
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
VerticalOptions = LayoutOptions.FillAndExpand,
|
|
|
|
|
HorizontalOptions = LayoutOptions.FillAndExpand
|
|
|
|
|
};
|
|
|
|
|
|
2018-06-15 14:34:47 +03:00
|
|
|
|
mainList.SetBinding(ListView.ItemsSourceProperty, "Items");
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
2018-06-15 14:34:47 +03:00
|
|
|
|
_viewModel = new MainViewModel();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
BindingContext = _viewModel;
|
2018-06-15 14:34:47 +03:00
|
|
|
|
loadData.Clicked += async (sender, e) =>
|
|
|
|
|
{
|
|
|
|
|
await LoadData();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mainList.ItemAppearing += OnItemAppearing;
|
|
|
|
|
|
2018-06-15 14:34:47 +03:00
|
|
|
|
Content = new StackLayout
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
Children = {
|
|
|
|
|
loadData,
|
|
|
|
|
mainList
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
|
|
|
|
|
{
|
2018-05-24 16:44:36 +03:00
|
|
|
|
if (e.Item == null)
|
|
|
|
|
return;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
var item = (int)e.Item;
|
|
|
|
|
if (!_viewModel.IsLoading && item == _viewModel.Items.Last())
|
|
|
|
|
await LoadData();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-15 14:34:47 +03:00
|
|
|
|
async Task LoadData()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2018-06-15 14:34:47 +03:00
|
|
|
|
await _viewModel.LoadData(_start, NumberOfRecords);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
_start = _start + NumberOfRecords;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class MainViewModel : INotifyPropertyChanged
|
|
|
|
|
{
|
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
|
|
2018-06-15 14:34:47 +03:00
|
|
|
|
public MainViewModel()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ObservableCollection<int> _items;
|
2018-06-15 14:34:47 +03:00
|
|
|
|
public ObservableCollection<int> Items
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
if (_items == null)
|
2018-06-15 14:34:47 +03:00
|
|
|
|
_items = new ObservableCollection<int>();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
return _items;
|
|
|
|
|
}
|
2018-06-15 14:34:47 +03:00
|
|
|
|
set
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
_items = value;
|
2018-06-15 14:34:47 +03:00
|
|
|
|
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool _isLoading;
|
2018-06-15 14:34:47 +03:00
|
|
|
|
public bool IsLoading
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
return _isLoading;
|
|
|
|
|
}
|
2018-06-15 14:34:47 +03:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_isLoading != value)
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
_isLoading = value;
|
2018-06-15 14:34:47 +03:00
|
|
|
|
PropertyChanged(this, new PropertyChangedEventArgs("IsLoading"));
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-12 22:30:27 +03:00
|
|
|
|
#pragma warning disable 1998 // considered for removal
|
2018-06-15 14:34:47 +03:00
|
|
|
|
public async Task LoadData(int start, int numberOfRecords)
|
2016-04-12 22:30:27 +03:00
|
|
|
|
#pragma warning restore 1998
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
IsLoading = true;
|
|
|
|
|
for (int counter = 0; counter < numberOfRecords; counter++)
|
2018-06-15 14:34:47 +03:00
|
|
|
|
Items.Add(start + counter);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
IsLoading = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-15 14:34:47 +03:00
|
|
|
|
|
|
|
|
|
#if UITEST
|
|
|
|
|
[Test]
|
|
|
|
|
public void NSRangeException()
|
|
|
|
|
{
|
|
|
|
|
RunningApp.WaitForElement(q => q.Marked("Load"));
|
|
|
|
|
RunningApp.Tap(q => q.Marked("Load"));
|
|
|
|
|
RunningApp.WaitForElement(q => q.Marked("5"));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|