DXCollectionView.LoadMoreCommand Property
Gets or sets the command executed when a user scrolls to the last item in the CollectionView to load new data items. This is a bindable property.
Namespace: DevExpress.Maui.CollectionView
Assembly: DevExpress.Maui.CollectionView.dll
NuGet Package: DevExpress.Maui.CollectionView
Declaration
public ICommand LoadMoreCommand { get; set; }
Property Value
Type | Description |
---|---|
ICommand | A command that exposes the ICommand interface. |
Remarks
When the IsLoadMoreEnabled property is enabled, DXCollectionView loads new data records from the bound data source when a user scrolls to the bottom (or to the right, if the Orientation property is set to Horizontal
) of the view. Define a load-more command in a view model and bind it to the LoadMoreCommand
property, or handle the LoadMoreCommand
event.
Set the DXCollectionView.IsRefreshing property to false
after data is loaded to hide the loading indicator in the collection view.
Example
In this example, the CollectionView displays a list of mail messages and loads a set of earlier messages when a user scrolls to the last item.
The application contains:
- A Model that defines application data.
- A View Model with a property that returns a data source for the CollectionView, a command that adds new items to a data source when a user reaches the end of the list, and a property that notifies the CollectionView about the loading activity status.
- A View that specifies how the CollectionView displays data.
Model
Create the following classes that define application data:
- MailData - Instances of this class are individual mail messages. Each message contains the name and email of the sender, subject, message text, and the time when the message was sent (generated randomly in code).
- MailMessageRepository - The MailMessages property of this class returns a collection of MailData objects (a data source for the CollectionView).
using System;
using System.Collections.Generic;
namespace CollectionView_LoadMore {
public class MailData {
public string SenderName { get; set; }
public string SenderEmail { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public DateTime MailTime { get; set; }
}
public class MailMessageRepository {
public List<MailData> MailMessages { get; private set; }
readonly Random random;
public MailMessageRepository() {
this.random = new Random((int)DateTime.Now.Ticks);
GenerateMessages();
}
public void GenerateMessages() {
MailMessages = new List<MailData>();
MailMessages.Add(
new MailData() {
SenderName = "Nancy Davolio",
SenderEmail = "NancyDavolio@devexpress.com",
Subject = "Choose between PPO and HMO Health Plan",
Body = "We need a final decision on whether we are planning " +
"on staying with a PPO Health Plan or we plan on switching to an HMO. " +
"We cannot proceed with compliance with the Affordable Health Act " +
"until we make this decision. " +
"John Heart: Samantha, I'm still reviewing costs. " +
"I am not in a position to make a final decision at this point.",
}
);
MailMessages.Add(
new MailData() {
SenderName = "Andrew Fuller",
SenderEmail = "AndrewFuller@devexpress.com",
Subject = "Google AdWords Strategy",
Body = "Make final decision on whether we are going " +
"to increase our Google AdWord spend " +
"based on our 2013 marketing plan."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Janet Leverling",
SenderEmail = "JanetLeverling@devexpress.com",
Subject = "New Brochures",
Body = "Review and the new brochure designs and give final approval. " +
"John Heart: we reviewed them all and forwarded an email with all changes we need " +
"to make to the brochures to comply with local regulations."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Margaret Peacock",
SenderEmail = "MargaretPeacock@devexpress.com",
Subject = "Website Re-Design Plan",
Body = "The changes in our brochure designs for 2013 require us " +
"to update key areas of our website."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Steven Buchanan",
SenderEmail = "StevenBuchanan@devexpress.com",
Subject = "Non-Compete Agreements",
Body = "Make final decision on whether our employees " +
"should sign non-compete agreements. " +
"Samantha Bright: Greta, we discussed this and we feel it is unnecessary " +
"to require non-compete agreements for employees."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Michael Suyama",
SenderEmail = "MichaelSuyama@devexpress.com",
Subject = "Update Employee Files with New NDA",
Body = "Management has approved new NDA. " +
"All employees must sign the new NDA and their employee files must be updated. " +
"Greta Sims: Having difficulty with a few employees. Will follow up by Email."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Robert King",
SenderEmail = "RobertKing@devexpress.com",
Subject = "Review Health Insurance Options Under the Affordable Care Act",
Body = "The changes in health insurance laws " +
"require that we review our existing coverage " +
"and update it to meet regulations. Samantha Bright will be point on this. " +
"Samantha Bright: " +
"Update - still working with the insurance company to update our coverages."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Laura Callahan",
SenderEmail = "LauraCallahan@devexpress.com",
Subject = "Give Final Approval for Refunds",
Body = "Refunds as a result of our 2013 TV recalls have been submitted. " +
"Need final approval to cut checks to customers. " +
"Samantha Bright: You can send the checks out mid-May."
}
);
MailMessages.Add(
new MailData() {
SenderName = "Anne Dodsworth",
SenderEmail = "AnneDodsworth@devexpress.com",
Subject = "Decide on Mobile Devices to Use in the Field",
Body = "We need to decide whether we are going " +
"to use Surface tablets in the field or go with iPad. " +
"I have prepared the pros and cons based on feedback from everyone in the IT dept. " +
"Arthur Miller: Surface."
}
);
GenerateRandomMailTime();
}
void GenerateRandomMailTime() {
DateTime currentDate = DateTime.Now.Date.AddMinutes(-1 * this.random.Next(1, 560));
foreach (MailData mail in MailMessages) {
currentDate = currentDate.AddMinutes(-1 * this.random.Next(1, 200));
mail.MailTime = currentDate;
}
}
}
}
View Model
Create the ViewModel class with the following properties to which the CollectionView should be bound:
- ItemSource - a collection of messages sorted in descending order according to when the message was sent.
- LoadMoreCommand - a command that randomly generates earlier messages and adds them to the item source.
- IsRefreshing - specifies whether the loading indicator is displayed in the CollectionView. When you implement the LoadMoreCommand command, set this property to false after you add new messages to the item source.
using System;
using Microsoft.Maui.Controls;
using System.Threading;
using System.Windows.Input;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace CollectionView_LoadMore{
public class ViewModel : INotifyPropertyChanged {
readonly MailMessageRepository repository;
DateTime currentDate = DateTime.Now;
readonly Random random;
public ViewModel(MailMessageRepository repository) {
this.random = new Random((int)DateTime.Now.Ticks);
this.repository = repository;
LoadMoreCommand = new Command(ExecuteLoadMoreCommand);
}
IList<MailData> itemSource;
public IList<MailData> ItemSource {
get { return itemSource; }
set {
if (itemSource != value) {
itemSource = value;
OnPropertyChanged("ItemSource");
}
}
}
bool isRefreshing = false;
public bool IsRefreshing {
get { return isRefreshing; }
set {
if (isRefreshing != value) {
isRefreshing = value;
OnPropertyChanged("IsRefreshing");
}
}
}
ICommand loadMoreCommand = null;
public ICommand LoadMoreCommand {
get { return loadMoreCommand; }
set {
if (loadMoreCommand != value) {
loadMoreCommand = value;
OnPropertyChanged("LoadMoreCommand");
}
}
}
void ExecuteLoadMoreCommand() {
Task.Run(() => {
Thread.Sleep(1000);
if (ItemSource == null)
ItemSource = new List<MailData>();
foreach (MailData mail in this.repository.MailMessages) {
this.currentDate = this.currentDate.AddMinutes(-1 * this.random.Next(5, 240));
ItemSource.Add(new MailData() {
SenderName = mail.SenderName,
SenderEmail = mail.SenderEmail,
Subject = mail.Subject,
Body = mail.Body,
MailTime = this.currentDate,
});
}
IsRefreshing = false;
});
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
In the MainPage.xaml.cs file, set the ContentPage’s BindingContext to a ViewModel object.
using Microsoft.Maui.Controls;
namespace CollectionView_LoadMore {
public partial class MainPage : ContentPage {
public MainPage() {
InitializeComponent();
BindingContext = new ViewModel(new MailMessageRepository());
}
}
}
View
In the MainPage.xaml file, create and set up the CollectionView:
- Add a DXCollectionView object to the page.
- Bind the ItemsSource property to the view model‘s ItemSource property.
- Set the IsLoadMoreEnabled to true to enable the CollectionView’s load-more functionality.
Bind the IsRefreshing andLoadMoreCommand
properties to the corresponding properties of the view model.
Use the IndicatorColor property to specify the loading indicator color. - Use the ItemTemplate property to define the appearance of list items. Bind the item template’s elements to properties of a MailData object.
Note
Note that the load-more functionality stops and the LoadMore
event is not raised if the number of items in the source has not been changed.
<ContentPage
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CollectionView_LoadMore.MainPage"
xmlns:dxcv="clr-namespace:DevExpress.Maui.CollectionView;assembly=DevExpress.Maui.CollectionView">
<dxcv:DXCollectionView x:Name="collectionView"
ItemsSource="{Binding ItemSource}"
IsLoadMoreEnabled="True"
IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}"
LoadMoreCommand="{Binding LoadMoreCommand}"
IndicatorColor="Lime">
<dxcv:DXCollectionView.ItemTemplate>
<DataTemplate>
<Grid ColumnSpacing="16" Padding="16, 14">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0"
Orientation="Vertical"
VerticalOptions="StartAndExpand">
<Label Text="{Binding SenderName}"
MaxLines="1"
FontAttributes="Bold"
TextColor="#55575c"/>
<Label Text="{Binding Subject}"
MaxLines="1"
TextColor="#55575c"/>
<Label Text="{Binding Body}"
MaxLines="1"
TextColor="#959aa0"/>
</StackLayout>
<StackLayout Grid.Column="1"
Orientation="Vertical"
VerticalOptions="StartAndExpand">
<Label TextColor="#959aa0"
FontSize="Small"
Text="{Binding MailTime, StringFormat='{0:ddd MM/dd}'}"/>
<Label TextColor="#959aa0"
FontSize="Small"
Text="{Binding MailTime, StringFormat='{0:hh:mm tt}'}"/>
</StackLayout>
</Grid>
</DataTemplate>
</dxcv:DXCollectionView.ItemTemplate>
</dxcv:DXCollectionView>
</ContentPage>