0
votes

I have a problem. I created a CollectionView that uses a custom ViewModel. In that ViewModel I do a webcall to my webpage to get 20 filenames of images. After I got the result I do foreach filename a call to get the ImageSource of that filename. Now I created a Load data incrementally code to load the CollectionView data in bundles of 20. Here is my xaml:

<ContentPage.Content>
    <StackLayout HorizontalOptions="Fill" Padding="15">
        <Frame IsClippedToBounds="True" HeightRequest="45" CornerRadius="5" Padding="0" BackgroundColor="Transparent">
            <Entry Placeholder="Search" ReturnType="Done" PlaceholderColor="Gray" x:Name="txtSearch" Margin="5,0,0,0" TextColor="White" />
        </Frame>

        <CollectionView ItemsSource="{Binding sourceList}" RemainingItemsThreshold="6"
            RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}">
            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical"
                Span="2" />
            </CollectionView.ItemsLayout>
            <CollectionView.ItemTemplate>
                <DataTemplate>

                    <ff:CachedImage
                Source="{Binding Source}"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                WidthRequest="{Binding WidthHeight}"
                HeightRequest="{Binding WidthHeight}">
                        <ff:CachedImage.GestureRecognizers>
                            <TapGestureRecognizer Tapped="imgTemplate_Clicked" />
                        </ff:CachedImage.GestureRecognizers>
                    </ff:CachedImage>

                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage.Content>

Here is the page constructor:

public TemplateList()
{
    InitializeComponent();

    TemplateListViewModel vm = new TemplateListViewModel();
    BindingContext = vm;
}

Here is the ViewModel:

public class TemplateListViewModel
{
    public ICommand LoadTemplates => new Command(LoadTemplateList);

    public int CurrentTemplateCountReceived;
    public ObservableCollection<TemplateSource> sourceList { get; set; }
    public double MemeWidthHeight { get; set; }

    public TemplateListViewModel()
    {
        CurrentTemplateCountReceived = 0;
        sourceList = new ObservableCollection<TemplateSource>();

        var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
        var width = mainDisplayInfo.Width;
        var density = mainDisplayInfo.Density;
        var ScaledWidth = width / density;

        MemeWidthHeight = (ScaledWidth / 2);

        loadingTemplates += onLoadingTemplates;
        LoadTemplateList();
    }

    private event EventHandler loadingTemplates = delegate { };

    private void LoadTemplateList()
    {
        loadingTemplates(this, EventArgs.Empty);
    }

    private async void onLoadingTemplates(object sender, EventArgs args)
    {
        List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);

        foreach (var template in templateList)
        {
            ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
            TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight= MemeWidthHeight, FileName = template.FileName };
            sourceList.Add(templateSource);
        }

        CurrentTemplateCountReceived = sourceList.Count;
    }
}

Now App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived); just returns me a list with filenames, but the problem is that it keeps doing webcalls when I got nothing to receive anymore. On my server I have 38 images, so after 2 webcalls the app got everything. After that the result that the app receives from the webcall is "Nothing".

So my question is:
How can I stop doing the webcalls when I am at the bottom of my CollectionView?

1
Stop making the requests. The CollectionView doesn't know that there isn't any more data to receive. You have to determine that in your code and stop making requests. If the API call doesn't return any data set some flag so that you know to stop making requests. - Jason

1 Answers

1
votes
bool moreData = true;

private async void onLoadingTemplates(object sender, EventArgs args)
    {
        if (!moreData) return;

        List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);

        if (templateList is null or templateList.Count == 0) {
          moreData = false;
          return;
        }

        foreach (var template in templateList)
        {
            ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
            TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight= MemeWidthHeight, FileName = template.FileName };
            sourceList.Add(templateSource);
        }

        CurrentTemplateCountReceived = sourceList.Count;
    }