Data Virtualization in WinUI DataGrid
18 May 202211 minutes to read
SfDataGrid provides support to handle the large amount of data through built-in virtualization features. With Data virtualization, SfDataGrid.View process the data in on-demand for better performance while loading large amount of data. Below are the different virtualization concepts available,
Concept | Usage |
---|---|
Data Virtualization
|
Use to load large amount of data in less time. |
Incremental Loading
|
Use to load subset of data from the services or servers in less time while loading and scrolling. On-demand request also supported. |
Data Virtualization
You can load large amount of data in less time by setting SfDataGrid.EnableDataVirtualization property to true
.
xmlns:dataGrid="using:Syncfusion.UI.Xaml.DataGrid"
<dataGrid:SfDataGrid x:Name="sfDataGrid"
AutoGenerateColumns="True"
ItemsSource="{Binding EmployeeDetails}"
EnableDataVirtualization="True">
this.sfDataGrid.EnableDataVirtualization = true;
Working with GridVirtualizingCollectionView
You can load the large amount of data in less time in another way using GridVirtualizingCollectionView which is derived from VirtualizingCollectionView to SfDataGrid.ItemsSource.
In the below code, ViewModel
defined with GridVirtualizingCollectionView
by passing complete records collection and bound to SfDataGrid.
public class ViewModel
{
private GridVirtualizingCollectionView _gridVirtualizingItemsSource;
public GridVirtualizingCollectionView GridVirtualizingItemsSource
{
get { return _gridVirtualizingItemsSource; }
set { _gridVirtualizingItemsSource = value; }
}
public ViewModel()
{
var _orders = this.GenerateOrders();
GridVirtualizingItemsSource = new GridVirtualizingCollectionView(_orders);
}
}
<dataGrid:SfDataGrid x:Name="sfDataGrid"
ColumnSizer="Star"
ItemsSource="{Binding GridVirtualizingItemsSource}" />
Limitations
- Data update using LiveDataUpdateMode is not supported.
- Details view is not supported.
- AllowFrozenGroupHeaders is not supported.
Incremental Loading
DataGrid supports to load the data incrementally using ISupportIncrementalLoading interface.
ISupportIncrementalLoading
interface has LoadMoreItemsAsync method which helps to load the data incrementally. LoadMoreItemsAsync
called in on-demand while scrolling based on HasMoreItems property.
If HasMoreItems
is false
, SfDataGrid stops calling LoadMoreItemsAsync
. SfDataGrid have IncrementalList which is derived from ISupportIncrementalLoading
. You can use IncrementalList
or create collection derived from ISupportIncrementalLoading
and bind it SfDataGrid.ItemsSource
.
In the below code, IncrementalList
is initialized by passing Action to its constructor for loading items incrementally.
<dataGrid:SfDataGrid x:Name="sfDataGrid"
AllowFiltering="True"
AutoGenerateColumns="True"
ItemsSource="{Binding IncrementalItemsSource}">
<dataGrid:SfDataGrid.DataContext>
<local:ViewModel />
</dataGrid:SfDataGrid.DataContext>
</dataGrid:SfDataGrid>
Public class ViewModel
{
public ViewModel()
{
IncrementalItemsSource = new IncrementalList<OrderInfo>(LoadMoreItems) { MaxItemCount = 1000 };
}
private IncrementalList<OrderInfo> _incrementalItemsSource;
public IncrementalList<OrderInfo> IncrementalItemsSource
{
get { return _incrementalItemsSource; }
set { _incrementalItemsSource = value; }
}
async Task<IList<OrderInfo>> LoadMoreItems(CancellationToken c, uint count, int baseIndex)
{
IList<OrderInfo> list = null;
await Task.Run(new Action(() =>
{
this.GenerateOrders();
list = _orders.Skip(baseIndex).Take(10).ToList();
}));
return list;
}
}
Load data using ISupportIncrementalLoading
You can fetch the data in some user action instead of scrolling using IncrementalList.LoadItems method.
In the below code, data fetched when you click the Load Items
button.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="90" />
</Grid.ColumnDefinitions>
<dataGrid:SfDataGrid x:Name="sfDataGrid"
Grid.Column="0"
DataFetchSize="5"
ItemsSource="{Binding IncrementalItemsSource}" >
<dataGrid:SfDataGrid.DataContext>
<local:ViewModel />
</dataGrid:SfDataGrid.DataContext>
</dataGrid:SfDataGrid>
<Button x:Name="LoadItems"
Grid.Column="1"
Command="{Binding DataContext.LoadItems,
ElementName=sfDataGrid}"
Content="Load Items" />
</Grid>
public class ViewModel : INotifyPropertyChanged
{
#region Members
NorthwindEntities northwindEntity;
#endregion
#region Properties
private IncrementalList<Order> incrementalItemsSource;
public IncrementalList<Order> IncrementalItemsSource
{
get { return incrementalItemsSource; }
set { incrementalItemsSource = value; RaisePropertyChanged("IncrementalItemsSource"); }
}
private DelegateCommand loadItems;
public DelegateCommand LoadItems
{
get
{
if (loadItems == null)
loadItems = new DelegateCommand(OnLoadItemsClicked, OnCanLoad);
return loadItems;
}
}
#endregion
#region Ctor
public ViewModel()
{
string uri = "http://services.odata.org/Northwind/Northwind.svc/";
incrementalItemsSource = new IncrementalList<Order>(LoadMoreItems) { MaxItemCount = 20 };
northwindEntity = new NorthwindEntities(new Uri(uri));
}
#endregion
#region Methods
async Task<IList<Order>> LoadMoreItems(CancellationToken c, uint count, int baseIndex)
{
IList<Order> list = null;
await Task.Run(new Action(() =>
{
DataServiceQuery<Order> query = (northwindEntity.Orders as
query = query.Skip<Order>(baseIndex).Take<Order>((int)count) as DataServiceQuery<Order>;
IAsyncResult ar = query.BeginExecute(null, null);
var items = query.EndExecute(ar);
list = items.ToList();
}));
return list;
}
private static bool OnCanLoad(object obj)
{
return true;
}
private void OnLoadItemsClicked(object obj)
{
LoadMoreItems(CancellationToken.None, 10, incrementalItemsSource.Count);
incrementalItemsSource.LoadMoreItemsAsync(10);
}
#endregion
#region INotifyPropertyChanged Member
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public void Dispose()
{
if (incrementalItemsSource != null)
incrementalItemsSource.Clear();
}
}
Limitations
- Deleting is not supported. You can code to delete row in application level.
- Summary is not calculated based on LiveDataUpdateMode.