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;
}
}