A. Vreeswijk
A. Vreeswijk

Reputation: 954

Xamarin Forms Stop loading data in CollectionView

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?

Upvotes: 0

Views: 1027

Answers (1)

Jason
Jason

Reputation: 89169

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;
    }

Upvotes: 1

Related Questions