I've just walk through this tutorial - http://docs.telerik.com/devtools/xamarin/controls/listview/features/listview-features-load-on-demand#automatic-mode
for implementation of LoadOnDemand - which is triggered Automatically from XAML code behind.
It work as expected at Android for me - *LoadOnDemand* event is triggered each time, i'm scrolling list down (and causing already last list existing elements visible). Each and every time, even if there is no objects be to be added. RadListView indeed didn't know if there are anything to be added to UI or not, that's why it fires *LoadOnDemand* event, in order to check it from code behind.
The problem is, that *LoadOnDemand* triggers only once for me at iOS - after first scrolling down. When I'm scrolling again and again, and I'm reaching the end of the list, *LoadOnDemand* is not triggers again.
It's not any specific case of my code - I'm just using simplest example form here - http://docs.telerik.com/devtools/xamarin/controls/listview/features/listview-features-load-on-demand#automatic-mode as mentioned before.
5 Answers, 1 is accepted
I'm not able to replicate what you're seeing. I have built you a sample app and offer some suggestions below.
Take a look at my attached example, by using ListViewLoadOnDemandCollection instead of ObservableCollection<T>, the RadListView will automatically calls the action when new items are needed and you do not need to use code behind / event handler!
ViewModel
private
int
bookCount;
public
StartPageViewModel()
{
BookSource =
new
ListViewLoadOnDemandCollection(LoadMoreBooks);
// Load some initial data
for
(var i = 0; i < 30; i++)
{
bookCount++;
BookSource.Add($
"Book {bookCount}"
);
}
}
/// <summary>
/// Data source for the RadListView
/// </summary>
public
ListViewLoadOnDemandCollection BookSource {
get
;
set
; }
/// <summary>
/// Method to load more items, triggered by the RadListView via the ListViewLoadOnDemandCollection
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>list of strings containing book names</returns>
private
IEnumerable<
object
> LoadMoreBooks(CancellationToken cancellationToken)
{
var result =
new
List<
string
>();
try
{
// Simulate 3 second connection latency
Task.Delay(3000, cancellationToken).Wait(cancellationToken);
for
(var i = 0; i < 20; i++)
{
bookCount++;
result.Add($
"Book {bookCount}"
);
}
return
result;
}
catch
(Exception ex)
{
return
null
;
}
}
XAML
<
Grid
>
<
Grid.BindingContext
>
<
viewModels:StartPageViewModel
x:Name
=
"ViewModel"
/>
</
Grid.BindingContext
>
<
telerikDataControls:RadListView
ItemsSource
=
"{Binding BookSource}"
IsLoadOnDemandEnabled
=
"True"
LoadOnDemandMode
=
"Automatic"
/>
</
Grid
>
If this doesn't help, please update my attached example so that it replicates what you're seeing and send it to us for further investigation.
Note: Since this is a public forum thread, you cannot attach projects. Instead I recommend opening a Support Ticket here (you have a support license with your trial and can attach your repro app). Support tickets carry a guaranteed response from the UI for Xamarin support team.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
I am not sure about all the details on how load on demand works. My main issue with the example provided in the Getting Started guides is that:
1. it loads infinite amount of data. In other words, it doesn't show how to end the load on demand when you have finished loading everything. Do you set IsLoadOnDemandEnabled = false? Do you set LoadOnDemandBufferItemsCount = 0?
2: What is the difference between IsLoadOnDemandEnabled and IsLoadOnDemandActive?
3. What does LoadOnDemandBufferItemsCount actually do? It says, "number of minimum items loaded ahead" which doesn't seem correct since how would the listview be able to load something ahead without calling the LoadOnDemand event?
I've replied in more depth to your support ticket on this subject, but to share the high level answers with the rest of the community.
1 - IsLoadOnDemandEnabled
When this is true, the RadListView will continue to run the event handler, or the ListViewLoadOnDemandCollection's Action, to fetch the next set of items. To turn it off, set IsLoadOnDemandEnabled to false.
2 - IsLoadOnDemandActive
This is toggled to true by the RadListView when it's currently fetching items, and false when it isn't.
3 - The LoadOnDemandBufferItemsCount sets when to make the next call for more items.
For example, let's say you set the buffer to 20. When user scrolls down, the RadListView will fire another fetch for items when it reaches the 20th item from the bottom of the list.
If you have any implementation problems, or have additional questions, please reply to the Support Ticket and we'll be happy to assist further.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Is there any possible way that after we get an amount of items to avoid/remove the current items in Loading mode with Collection.
For example I have 20 items displayed on screen but when I want to load the others Items, can I move the current 20 items and load the 20th items which are in queue, because for LoadOnDemandMode="Manual" this could work but not for Automatically.
And I tried also LoadOnDemandBufferItemsCount but seems not to work for me when I have two items and the LoadOnDemandMode="Automatic".
Best Regards
Aridon
As long as your action isn't a static method, you can reference the collection and manually remove the items.
Example
In this simple example, I remove the first 20 items in the list each time I fetch more.
public
class
MyViewModel
{
public
MyViewModel()
{
MyItems =
new
LoadOnDemandCollection<
string
>(LoadItems);
}
public
LoadOnDemandCollection<
string
> MyItems {
get
;
set
; }
private
IEnumerable LoadItems(CancellationToken arg)
{
// Remove what you want from the list
for
(
int
i = 0; i < 19; i++)
{
MyItems.RemoveAt(i);
}
// get and return the items you want added
var items = GetItemsFromApi();
return
items;
}
private
IEnumerable GetItemsFromApi()
{
return
new
List<
string
>(); // placeholder for list of items from the data source
}
}
Warning:
If you do this, make sure you don't get caught in an infinite loop. If you remove too many items, you could end up with less items than the LoadOnDemandBufferItemsCount and be stuck in a loop because the RadListView initiates another call for items when the end of the list is less than the buffer count away.
For example, let's say your buffer count is set to 20 (the default) and you remove the first 20 when you add the next 20 items from the data source. This means the the RadListView will always only have 20 items in it and infinitely keep loading more. The fix for such a case is to make sure your call for more items returns a count at least double the LoadOnDemandBufferItemsCount count.
Further support
If you have any further trouble, you can open a Support Ticket here and attach your code. A Support Ticket carries a guaranteed response time from one of the engineers responsible for the Xamairn components.
I see that your account doesn't have a license for UI for Xamarin, I'm guessing that you're using a license that was purchased by your employer or team lead? This is not uncommon scenario and we have an `easy button` solution to resolve it.
Go here to the Manage Licensed Users portal and have them add you as a Licensed User using your email address. It takes less than 30 seconds to do this and will give you get access to the Support Ticket system and will cease breaking the Terms of Service agreement (we have a per-developer license policy).
Note that if they only have one license, they'll need to remove themselves as the Licensed User, but they still own the license and can change Licensed User again at any time.
Wrapping Up
If you're still having trouble and you're still waiting for you to be assigned as the Licensed User, reply back here with all the code I need to reproduce the issue and I'll investigate further.
Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik