Issue
I have many records on database, next to 5000 records on a table and to get this informations I am trying to use OFFSET and LIMIT at my webservice, it works well. On Xamarin I am trying to create an infinite ListView that will loading data while user make the scroll. The problem that I cannot do this works.
How do I to fix this ?
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage 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"
x:Class="MyApp.View.LimitOffsetTest">
<ContentPage.Content>
<StackLayout>
<ListView x:Name="MyList" ItemAppearing="OnItemAppearing" VerticalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding numero}"></Label>
<Label Text="{Binding valor}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout HorizontalOptions="FillAndExpand" BackgroundColor="Yellow">
<Label x:Name="FooterLoading" Text="Loading..." IsVisible="False" TextColor="Red" FontAttributes="Bold" HorizontalOptions="Center"></Label>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
LimitOffsetTest
public partial class LimitOffsetTest : ContentPage{
private SmartCollection<NumerosSorteioDTO> smartCollection;
private static ConcursoDTO _values = new ConcursoDTO();
private static int OFFSET = 0;
private const int LIMIT = 5;
public LimitOffsetTest(){
InitializeComponent();
firstLoad();
}
private void firstLoad(){
try{
FooterLoading.IsVisible = true;
smartCollection = new SmartCollection<NumerosSorteioDTO>();
_values.offset = OFFSET;
_values.limit = LIMIT;
ConcursoDTO dto = ConcursoService.GetNumerosSorteConcursoLO(_values);
smartCollection.AddRange(dto.numeros);
this.BindingContext = smartCollection;
this.MyList.ItemsSource = smartCollection;
}catch(Exception e){
Debug.WriteLine("Erro: " + e.Message);
}
finally{
FooterLoading.IsVisible = false;
}
}
private void OnItemAppearing(object sender, ItemVisibilityEventArgs args){
try{
FooterLoading.IsVisible = true;
var _item = (NumerosSorteioDTO)args.Item;
if (_item == smartCollection[smartCollection.Count - 1])
{
_values.offset += 5;
ConcursoDTO dto = ConcursoService.GetNumerosSorteConcursoLO(_values);
smartCollection.AddRange(dto.numeros);
}
} catch(Exception e){
Debug.WriteLine("Erro: " + e.Message);
}finally{
FooterLoading.IsVisible = false;
}
}
}//class
Controller
public class SmartCollection<T> : ObservableCollection<T>
{
public SmartCollection()
: base()
{
}
public SmartCollection(IEnumerable<T> collection)
: base(collection)
{
}
public SmartCollection(List<T> list)
: base(list)
{
}
public void AddRange(IEnumerable<T> range)
{
foreach (var item in range)
{
Items.Add(item);
}
this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public void Reset(IEnumerable<T> range)
{
this.Items.Clear();
AddRange(range);
}
}
Solution
I use your code and add some local data, your codes works well on my side. You should check whether ConcursoService.GetNumerosSorteConcursoLO get the right data:
ConcursoDTO dto = ConcursoService.GetNumerosSorteConcursoLO(_values);
Here is some part of my codes:
private void OnItemAppearing(object sender, ItemVisibilityEventArgs args)
{
try
{
FooterLoading.IsVisible = true;
var _item = (NumerosSorteioDTO)args.Item;
if (_item == smartCollection[smartCollection.Count - 1])
{
_values.offset += 5;
//ConcursoDTO dto = ConcursoService.GetNumerosSorteConcursoLO(_values);
NumerosSorteioDTO obj1 = new NumerosSorteioDTO { numero = "1", valor = "1" };
NumerosSorteioDTO obj2 = new NumerosSorteioDTO { numero = "2", valor = "2" };
NumerosSorteioDTO obj3 = new NumerosSorteioDTO { numero = "3", valor = "3" };
NumerosSorteioDTO obj4 = new NumerosSorteioDTO { numero = "4", valor = "4" };
NumerosSorteioDTO obj5 = new NumerosSorteioDTO { numero = "5", valor = "5" };
ConcursoDTO dto = new ConcursoDTO();
dto.numeros.Add(obj1);
dto.numeros.Add(obj2);
dto.numeros.Add(obj3);
dto.numeros.Add(obj4);
dto.numeros.Add(obj5);
smartCollection.AddRange(dto.numeros);
}
}
catch (Exception e)
{
Debug.WriteLine("Erro: " + e.Message);
}
finally
{
FooterLoading.IsVisible = false;
}
}
I uploaded my test project here and you can check.
Here is the result:
Answered By - nevermore

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.