Data Grid for .NET MAUI – Version 1.0.1 Demo
Published:
Modified:
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). Warning – templated columns (added in version 1.0.1)!
The source code is available on GitHub – https://github.com/Monsalma/Monsalma.Maui.Controls/tree/main/Monsalma-Maui-v010001.
To get started, please download Monsalma.Maui.Controls NuGet package: https://www.nuget.org/packages/Monsalma.Maui.Controls/1.0.1-beta.
Additional resources:
Model (Data)
Instances of the WorldCupWinner
class (Monsalma_Maui_v010001.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; }
}
View Model
MainViewModel
(Monsalma_Maui_v010001.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_v010001.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_v010001.Data"
xmlns:viewmodels="clr-namespace:Monsalma_Maui_v010001.ViewModels"
xmlns:datatemplateselectors="clr-namespace:Monsalma_Maui_v010001.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}" />
Data Grid Definition
DataGrid
definition should be pretty straightforward. It it’s not, please refer to the previous demo (Monsalma-Maui-v010000).
<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. For Year
and GoldenBallWinner
we’ll use a simple text column (DataGridColumnText
). Nothing new there. For Country
we’ll use a templated column (DataGridColumnTemplated
):
<controls:DataGrid.Columns>
<controls:DataGridColumnText
Width="Auto"
MinWidth="100"
DataBinding="Year"
HeaderText="Year"
CellPadding="5"
CellHorizontalAlignment="Center"
CellVerticalAlignment="Center" />
<controls:DataGridColumnTemplated
Width="*"
MinWidth="100"
MaxWidth="200"
HeaderText="Country"
CellPadding="5"
CellHorizontalAlignment="Start"
CellVerticalAlignment="Center"
CellTemplate="{StaticResource Key=countryDataTemplateSelector}" />
<controls:DataGridColumnText
Width="*"
MinWidth="100"
MaxWidth="200"
DataBinding="GoldenBallWinner"
HeaderText="Golden Ball Winner"
CellPadding="5"
CellHorizontalAlignment="Start"
CellVerticalAlignment="Center" />
</controls:DataGrid.Columns>
Conclusion
The important thing to learn from this demo is how to use data templates, data template selector and templated column. This is the single line of code that brings all 3 concepts together:
CellTemplate="{StaticResource Key=countryDataTemplateSelector}" />
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;
}
}