Manual Data Source Operations
The ListView lets you fetch the current page of data on demand through the OnRead
event. This can let you optimize database queries and return only a small number of records.
In this article you will find examples how to:
- implement custom paging
- implement filtering and sorting
Custom Paging
This is, effectively, loading data on demand only when the user goes to a certain page, as opposed to the default case where you fetch all the data items initially.
To implement your own paging in the listview, you need to:
- Handle the
OnRead
event. - Set the current page of data to the
args.Data
property of the event argument. - Set the
args.Total
property to the total number of items on all pages, so that the pager displays correct information. - Set the
TItem
attribute of the ListView to the model type. - Do not set the component
Data
attribute.
@* This example simulates fetching the page data from a service *@
<TelerikListView TItem="@SampleData"
OnRead="@OnReadHandler"
Pageable="true" PageSize="@PageSize">
<Template>
<h6>@context.Name</h6>
</Template>
</TelerikListView>
@code{
int PageSize { get; set; } = 15;
async Task OnReadHandler(ListViewReadEventArgs args)
{
args.Data = await GetListViewPageData(args.Request.Page, args.Request.PageSize);
args.Total = await GetTotalItemsCount();
}
async Task<List<SampleData>> GetListViewPageData(int pageIndex, int pageSize)
{
// this is just a simulation of a service call, implement as appropriate in your app
await Task.Delay(500); // simulate real network/database delay. Remove in a real app
return _allData.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
async Task<int> GetTotalItemsCount()
{
return _allData.Count;
}
private List<SampleData> _allData { get; set; } = Enumerable.Range(1, 500).Select(x => new SampleData
{
Id = x,
Name = $"Name {x}"
}).ToList();
public class SampleData
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Filter and Sort
While the listview does not have built-in UI for filtering and sorting like a grid does, you can add your own components to invoke such actions and simply update the data source of the component.
The example below shows a relatively simple way to filter and sort over all data in the current view model without loading data on demand.
@* This is one sample implementation, you should optimize the queries according to your project and needs *@
<TelerikListView Data="@ListViewData" Pageable="true">
<HeaderTemplate>
Sort Name: <TelerikDropDownList Data="@( new List<string>() { "None", "Ascending", "Descending" } )"
Value="@sort" ValueChanged="@( (string dir) => SortName(dir) )" />
<br />
Filter: <TelerikTextBox Value="@filter" ValueChanged="@( (string val) => FilterData(val) )" />
</HeaderTemplate>
<Template>
<h6>@context.Name</h6>
</Template>
</TelerikListView>
@code{
int TotalItems { get; set; }
List<SampleData> ListViewData { get; set; }
string sort { get; set; }
string filter { get; set; }
private List<SampleData> _allData { get; set; } = Enumerable.Range(1, 500).Select(x => new SampleData
{
Id = x,
Name = $"Name {x}"
}).ToList();
protected override void OnInitialized()
{
ListViewData = new List<SampleData>(_allData);
}
void FilterData(string filterVal)
{
filter = filterVal;
string lowercaseFilter = filterVal.ToLowerInvariant();
// you can optimize and implement this query as desired
ListViewData = _allData.Where(itm => itm.Name.ToLowerInvariant().Contains(lowercaseFilter) || itm.Id.ToString() == lowercaseFilter).ToList();
}
void SortName(string dir)
{
sort = dir;
// you can optimize and implement this query as desired
switch (dir)
{
case "Ascending":
ListViewData = ListViewData.OrderBy(o => o.Name).ToList();
break;
case "Descending":
ListViewData = ListViewData.OrderByDescending(o => o.Name).ToList();
break;
default:
ListViewData = ListViewData.OrderBy(o => o.Id).ToList();
break;
}
}
public class SampleData
{
public int Id { get; set; }
public string Name { get; set; }
}
}
To optimize queries, you can store the
DataSourceRequest
from theOnRead
event in a view-model field to easily access the current page.You can also use the Telerik extension methods - the
.ToDataSourceResult()
that takes aDataSourceRequest
argument over the full collection of data and add filer and sort descriptors to it. Examples of doing that are available in the Live Demos: ListView Filtering and ListView Sorting