This is a migrated thread and some comments may be shown as answers.

"Items are Completely Loaded and Displayed" Event

4 Answers 939 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Bruce
Top achievements
Rank 1
Bruce asked on 09 Aug 2017, 07:53 PM

I see no event representing this occurrence - All of the items in the RadListView are visually built and ready for user interaction.

I have a wait spinner I display when a control is not ready for user interaction or when a screen is being built.  I can easily make a change to a RadListView's ItemSource, but it takes a bit for the display to be properly built.  Without an event the represents the finishing of the display, I have no known spot at which I can turn off my wait spinner.

I'm open to any and all ideas.  Additionally, consider this an enhancement request for just such an event.

4 Answers, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 10 Aug 2017, 09:15 PM
Hi Bruce,

The RadListView uses UI Virtualization. It will render some items above and below the view port, but not all of the items. They'll be rendered as they're needed. 

Therefore, you can turn off your busy indicator once the data is loaded into the collection you have bound to the ItemsSource. 

Examples

In the XAML, I have a RadListView and a RadBusyIndicator:

<ContentPage.BindingContext>
    <portable:ViewModel />
</ContentPage.BindingContext>
     
<Grid>
    <telerikDataControls:RadListView x:Name="listView" ItemsSource="{Binding Source}">
        <telerikDataControls:RadListView.ItemTemplate>
            <DataTemplate>
                <listView:ListViewTextCell Text="{Binding Name}" />
            </DataTemplate>
        </telerikDataControls:RadListView.ItemTemplate>
    </telerikDataControls:RadListView>
         
    <YourBusySpinner IsVisible-OR-IsBusy="{Binding IsBusy}" />
</Grid>


And in the ViewModel, notice I toggle the IsBusy property on and off around the data loading:

public class ViewModel : NotifyPropertyChangedBase
{
    private ObservableCollection<SourceItem> source;
    private bool isBusy;
 
    public ViewModel()
    {
             
    }
 
    public ObservableCollection<SourceItem> Source => source ?? (source = new ObservableCollection<SourceItem>());
 
    public bool IsBusy
    {
        get => isBusy;
        set { isBusy = value; OnPropertyChanged();}
    }
 
    public void LoadItems()
    {
        IsBusy = true;
 
        for (int i = 0; i < 30; i++)
        {
            Task.Delay(100);
 
            Source.Add(new SourceItem($"Item {i}"));
        }
 
        IsBusy = false;
    }
}



Alternative - LoadOnDemand

Alternatively, if you're using incremental data calls, you can use the built-in LoadOnDemand features and only show the spinner when the ListView is fetching the next set of items.

I've attached a demo that shows how to do this with automatic LoadOnDemand, here's the method that gets the items whenever the user scrolls down:

private IEnumerable<object> GetMoreItems(CancellationToken cancelationToken)
{
    List<string> result = new List<string>();
 
    try
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            IsBusy = true;
        });
 
        //simulate 2 second delay
        Task.Delay(2000, cancelationToken).Wait(cancelationToken);
 
        lodTriggerCount++;
 
        foreach (string item in Enum.GetNames(typeof(DayOfWeek)))
            result.Add($"LOD: {lodTriggerCount} - {item}");
 
        return result;
    }
    catch (Exception ex)
    {
        return null;
    }
    finally
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            IsBusy = false;
        });
    }
}

Take a look at the demo, find all the code on StartPage.xaml and StartPage.xaml.cs. When you run it, scroll down after the first set of items load.


Wrapping Up

If you have any further questions, please open a support ticket here so that you can share your code and we can investigate further.


Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Bruce
Top achievements
Rank 1
answered on 11 Aug 2017, 02:40 PM

As always, thanks for looking into it and for your reply, Lance.

Your suggestion works just fine and dandy, but for one small problem - I'm binding my ItemSource, not setting it programmatically.  I can, and will, switch to setting it programmatically if that's my only option for now, but I will nonetheless suggest that an event that represents "Items are Completely Loaded and Displayed" be added.

If this is my only option for now, just let me know and I'll mark this thread as answered.

0
Lance | Manager Technical Support
Telerik team
answered on 11 Aug 2017, 02:53 PM
Hello Bruce,

Both of my examples are using data binding, the C# you see is in the pasted code is the View Model. In the attached runnable demo, it uses data binding and automatic load on demand.

In any of these cases, your approach will be the same: monitor the loading of the data, as opposed to watching the RadListView for cues to when the data is done.

1 - Have a boolean property "IsBusy" (or similar) in your ViewModel
2 - In the view, bind your spinner to the IsBusy property
2 - Trip the IsBusy flag to true before fetching your data
3 - Trip the IsBusy flag to false when it's done.

I hope this was helpful, let me know if you have any additional questions.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Bruce
Top achievements
Rank 1
answered on 11 Aug 2017, 02:56 PM

My apologies; I read too quickly.

Thanks for your help.

Tags
ListView
Asked by
Bruce
Top achievements
Rank 1
Answers by
Lance | Manager Technical Support
Telerik team
Bruce
Top achievements
Rank 1
Share this question
or