Data Grid for .NET MAUI – Version 1.0.2 Demo

Published:

Modified:

Similar to the previous demo, this one is for all soccer fans out there. We’ll be using Monsalma DataGrid control to display all World Cup winners (and Golden Ball winners).

The source code is available on GitHub – https://github.com/Monsalma/Monsalma.Maui.Controls/tree/main/Monsalma-Maui-v010002.

To get started, please download Monsalma.Maui.Controls NuGet package: https://www.nuget.org/packages/Monsalma.Maui.Controls/1.0.2.

Additional resources:

Model (Data)

Instances of the WorldCupWinner class (Monsalma_Maui_v010002.Data.WorldCupWinner) contain the data:

public class WorldCupWinner 
{ 
	public int Year { get; set; } 
	public string Country { get; set; } 
	public string ImageSource { get; set; } 
	public string GoldenBallWinner { get; set; } 

	public bool IsCountryReadOnly { get => Year < 2000; } 
} 

View Model

MainViewModel (Monsalma_Maui_v010002.ViewModels.MainViewModel) creates a list of all world cup winners:

public MainViewModel()  
{ 
	WorldCupWinners = []; 

	WorldCupWinners.Add(new WorldCupWinner() { Year = 1986, Country = "Argentina", ImageSource="argentina.png", GoldenBallWinner = "Diego Maradona" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 1990, Country = "Germany", ImageSource = "germany.png", GoldenBallWinner = "Salvatore Schillaci" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 1994, Country = "Brazil", ImageSource = "brazil.png", GoldenBallWinner = "Romário" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 1998, Country = "France", ImageSource = "france.png", GoldenBallWinner = "Ronaldo" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 2002, Country = "Brazil", ImageSource = "brazil.png", GoldenBallWinner = "Oliver Kahn" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 2006, Country = "Italy", ImageSource = "italy.png", GoldenBallWinner = "Zinedine Zidane" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 2010, Country = "Spain", ImageSource = "spain.png", GoldenBallWinner = "Diego Forlán" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 2014, Country = "Germany", ImageSource = "germany.png", GoldenBallWinner = "Lionel Messi" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 2018, Country = "France", ImageSource = "france.png", GoldenBallWinner = "Luka Modrić" }); 
	WorldCupWinners.Add(new WorldCupWinner() { Year = 2022, Country = "Argentina", ImageSource = "argentina.png", GoldenBallWinner = "Lionel Messi" }); 
} 

View (XAML)

MainPage (Monsalma_Maui_v010002.MainPage) is the only page used in this demo.

Imports

First we import the package (Monsalma.Maui.Controls) and local namespaces (data, template selectors and view model):

xmlns:controls="clr-namespace:Monsalma.Maui.Controls;assembly=Monsalma.Maui.Controls" 
xmlns:data="clr-namespace:Monsalma_Maui_v010002.Data" 
xmlns:viewmodels="clr-namespace:Monsalma_Maui_v010002.ViewModels" 
xmlns:datatemplateselectors="clr-namespace:Monsalma_Maui_v010002.DataTemplateSelectors" 

Row Styles

Then we define row styles (header row, odd row, even row and selected row) for the data grid control:

<Style 
	TargetType="controls:DataGridRowHeader" 
	x:Key="HeaderRowStyle"> 

	<Setter 
		Property="CellBackgroundColor" 
		Value="{StaticResource Key=Primary}" /> 

	<Setter 
		Property="CellForegroundColor" 
		Value="{StaticResource Key=White}" /> 
</Style> 

<Style 
	TargetType="controls:DataGridRowRegular" 
	x:Key="RegularOddRowStyle"> 

	<Setter 
		Property="CellBackgroundColor" 
		Value="{StaticResource Key=White}" /> 

	<Setter 
		Property="CellForegroundColor" 
		Value="{StaticResource Key=Black}" /> 
</Style> 

<Style 
	TargetType="controls:DataGridRowRegular" 
	x:Key="RegularEvenRowStyle"> 

	<Setter 
		Property="CellBackgroundColor" 
		Value="{StaticResource Key=Gray100}" /> 

	<Setter 
		Property="CellForegroundColor" 
		Value="{StaticResource Key=Black}" /> 
</Style> 

<Style 
	TargetType="controls:DataGridRowRegular" 
	x:Key="SelectedRowStyle"> 

	<Setter 
		Property="CellBackgroundColor" 
		Value="{StaticResource Key=Yellow100Accent}" /> 

	<Setter 
		Property="CellForegroundColor" 
		Value="{StaticResource Key=Black}" /> 
</Style>

Data Templates

We define data templates and data template selector, to be used later on. 20th century winners template is slightly different than the 21st century template. This is just to illustrate the power of templates.

<DataTemplate 
	x:Key="century20Template" 
	x:DataType="data:WorldCupWinner"> 

	<Grid 
		Padding="5" 
		BindingContext="{Binding Path=BindingContext, Source={RelativeSource TemplatedParent}}" 
		HorizontalOptions="Fill" 
		ColumnDefinitions="Auto, Auto"> 

	<Image 
		Grid.Column="0" 
		WidthRequest="32" 
		HeightRequest="24" 
		VerticalOptions="Center" 
		Source="{Binding ImageSource}" /> 
	<Label 
		Grid.Column="1" 
		Padding="5" 
		VerticalOptions="Center" 
		Text="{Binding Country}" /> 
	</Grid> 
</DataTemplate> 

<DataTemplate 
	x:Key="century21Template" 
	x:DataType="data:WorldCupWinner"> 

	<Grid 
		Padding="5" 
		BindingContext="{Binding Path=BindingContext, Source={RelativeSource TemplatedParent}}" 
		HorizontalOptions="Fill" 
		ColumnDefinitions="Auto, Auto"> 

	<Label 
		Grid.Column="0" 
		Padding="5" 
		VerticalOptions="Center" 
		Text="{Binding Country}" /> 
	<Image 
		Grid.Column="1" 
		WidthRequest="32" 
		HeightRequest="24" 
		VerticalOptions="Center" 
		Source="{Binding ImageSource}" /> 
	</Grid> 
</DataTemplate> 

<datatemplateselectors:WorldCupWinnerDataTemplateSelector 
	x:Key="countryDataTemplateSelector" 
	Century20Template="{StaticResource Key=century20Template}" 
	Century2021Template="{StaticResource Key=century21Template}" /> 

In addition to data templates and data template selector defined above, which were used in the previous demo as well as in this one, in this version we introduce the edit template (to be used later on, when defining columns):

<DataTemplate 
	x:Key="countryEditTemplate" 
	x:DataType="data:WorldCupWinner"> 

	<Entry 
		BindingContext="{Binding Path=BindingContext, Source={RelativeSource TemplatedParent}}" 
		Text="{Binding Country}" 
		HorizontalTextAlignment="End" />

Data Grid Definition

DataGrid definition should be pretty straightforward. It it’s not, please refer to the previous demo (Monsalma-Maui-v010001).

<controls:DataGrid 
	Margin="5" 
	Items="{Binding WorldCupWinners}" 
	SelectionMode="Multiple" 
	SelectedItem="{Binding SelectedWorldCupWinner, Mode=TwoWay}" 
	SelectedItems="{Binding SelectedWorldCupWinners, Mode=TwoWay}" 
	HeaderRowStyle="{StaticResource Key=HeaderRowStyle}" 
	RegularOddRowStyle="{StaticResource Key=RegularOddRowStyle}" 
	RegularEvenRowStyle="{StaticResource Key=RegularEvenRowStyle}" 
	SelectedRowStyle="{StaticResource Key=SelectedRowStyle}"> 

Column Definition

Next, it’s time to define our columns. Year and GoldenBallWinner columns are pretty much the same as in the previous demo. Now I’d like to highlight the usage of CellIsReadOnlyBinding, CellTemplate and CellEditTemplate:

<controls:DataGridColumnTemplated 
	Width="*" 
	MinWidth="100" 
	MaxWidth="200" 
	DataBinding="Country" 
	CellIsReadOnlyBinding="IsCountryReadOnly" 
	HeaderText="Country" 
	CellPadding="5" 
	CellHorizontalAlignment="Start" 
	CellVerticalAlignment="Center" 
	CellTemplate="{StaticResource Key=countryDataTemplateSelector}" 
	CellEditTemplate="{StaticResource Key=countryEditTemplate}" />

CellIsReadOnlyBinding binds to the IsCountryReadOnly property of the WorldCupWinner class. If the bound value returns true, then the data template defined by CellTemplate is used. Otherwise, CellEditTemplate determines which data template to use.

Data Template Selector

DataTemplateSelector class is selecting Century20Template or Century2021Template based on the year (Year property):

internal class WorldCupWinnerDataTemplateSelector : DataTemplateSelector 
{ 
	public DataTemplate Century20Template { get; set; } 
	public DataTemplate Century2021Template { get; set; } 

	protected override DataTemplate OnSelectTemplate(object item, BindableObject container) 
	{ 
		return ((WorldCupWinner)item).Year >= 2000 ? Century2021Template : Century20Template; 
	} 
} 

Screenshots

Windows – CellTemplate used (CellIsReadOnlyBinding is true)

Data Grid for .NET MAUI - Version 1.0.2 - Demo - World Cup Winners - Windows
Data Grid for .NET MAUI – Version 1.0.2 – Demo – World Cup Winners – Windows

Android – CellTemplate used (CellIsReadOnlyBinding is true)

Data Grid for .NET MAUI - Version 1.0.2 - Demo - World Cup Winners - Android - CellTemplate
Data Grid for .NET MAUI – Version 1.0.2 – Demo – World Cup Winners – Android – CellTemplate

Android – CellEditTemplate used (CellIsReadOnlyBinding is false)

Data Grid for .NET MAUI - Version 1.0.2 - Demo - World Cup Winners - Android - CellEditTemplate
Data Grid for .NET MAUI – Version 1.0.2 – Demo – World Cup Winners – Android – CellEditTemplate