.NET MAUI DataGrid Data Binding: Binding to a Collection
This article lists the source types supported by the Telerik UI for .NET MAUI DataGrid. It guides you through the process of binding the DataGrid control to a collection of items and configuring the data binding for its columns.
Supported Collection Sources
To populate the DataGrid with data, use the ItemsSource
property of the control. For compatibility reasons, the ItemsSource
property of the .NET MAUI DataGrid is declared as a System.Object
type. However, using collections that implement the IEnumerable
interface is recommended as it gives you more flexibility.
Binding to an ObservableCollection
When you bind the RadDataGrid
to a collection that implements the INotifyCollectionChanged
interface, the DataGrid reflects and displays all changes to that collection, for example, any adding or removing of data items. The .NET MAUI framework implements the INotifyCollectionChanged
interface in the ObservableCollection<T>
class.
Implementations of the System.ComponentModel.ICollection
interface are also fully supported. When using such collection sources, the RadDataGrid
automatically picks up any group, sort, or filter descriptions defined in the collection and uses them to display the data. This makes the System.ComponentModel.ICollection
interface implementations the recommended collection source for the DataGrid.
The next example demonstrates how to bind the DataGrid to an ObservableCollection
. For this example, the DataGrid control is bound to a collection of Club
objects. Note that the Club
class inherits from NotifyPropertyChangedBase
, which is the Telerik implementation of the INotifyPropertyChanged
interface.
1. Define the Club
class:
public class Club : NotifyPropertyChangedBase
{
private string name;
private DateTime established;
private int stadiumCapacity;
private bool isChampion;
private string country;
private string city;
private string championship;
private double? revenue;
public Club(string name, DateTime established, int stadiumCapacity, string country, string city, string championship, double? revenue)
{
Name = name;
Established = established;
StadiumCapacity = stadiumCapacity;
Country = country;
City = city;
Championship = championship;
Revenue = revenue;
}
public string Name
{
get { return this.name; }
set { this.UpdateValue(ref this.name, value); }
}
public DateTime Established
{
get { return this.established; }
set { this.UpdateValue(ref this.established, value); }
}
public int StadiumCapacity
{
get { return this.stadiumCapacity; }
set { this.UpdateValue(ref this.stadiumCapacity, value); }
}
public bool IsChampion
{
get { return this.isChampion; }
set { this.UpdateValue(ref this.isChampion, value); }
}
public string Country
{
get { return this.country; }
set { this.UpdateValue(ref this.country, value); }
}
public string City
{
get { return this.city; }
set { this.UpdateValue(ref this.city, value); }
}
public string Championship
{
get { return this.championship; }
set { this.UpdateValue(ref this.championship, value); }
}
public double? Revenue
{
get { return this.revenue; }
set { this.UpdateValue(ref this.revenue, value); }
}
public List<string> Championships => new List<string> { "UEFA Champions League", "Premier League", "La Liga" };
}
2. Create an ObservableCollection
in the ViewModel
class:
public class ViewModel
{
private ObservableCollection<Club> clubs;
public ObservableCollection<Club> Clubs => clubs ?? (clubs = CreateClubs());
private ObservableCollection<Club> CreateClubs()
{
return new ObservableCollection<Club>
{
new Club("UK Liverpool ", new DateTime(1892, 1, 1), 54074, "England", "Liverpool", "Premier League", null),
new Club("Manchester Utd.", new DateTime(1878, 1, 1), 74310, "England", "Manchester", "Premier League", 594.3) { IsChampion = true },
new Club("Chelsea", new DateTime(1905, 1, 1), 42055, "England", "London","UEFA Champions League", 481.3),
new Club("Barcelona", new DateTime(1899, 1, 1), 99354, "Spain", "Barcelona", "La Liga", 540.5)
};
}
}
3. Bind the collection to the RadDataGrid
control:
<telerik:RadDataGrid x:Name="grid"
ItemsSource="{Binding Clubs}" />
4. Add the telerik
namespace:
xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"
Binding the Columns
By default, DataGrid will generate typed columns automatically based on the public properties of the underlying data objects. When, for example, you set the ItemsSource
of the RadDataGrid
to a collection of clubs (see the sample above), the control will create a separate column for each public property of the Club
object.
To disable the automatic generation of DataGrid columns and manually define them, set the control's AutoGenerateColumns
property to False
and manually populate the Columns
collection.
1. Define the columns:
<telerik:RadDataGrid x:Name="grid"
ItemsSource="{Binding Clubs}"
AutoGenerateColumns="False">
<telerik:RadDataGrid.BindingContext>
<local:ViewModel />
</telerik:RadDataGrid.BindingContext>
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn PropertyName="Name"
HeaderText="Name">
<telerik:DataGridTextColumn.CellContentStyle>
<Style TargetType="telerik:DataGridTextCellAppearance">
<Setter Property="TextColor" Value="#018383" />
<Setter Property="SelectedTextColor" Value="#A55200" />
<Setter Property="FontSize" Value="15" />
</Style>
</telerik:DataGridTextColumn.CellContentStyle>
</telerik:DataGridTextColumn>
<telerik:DataGridNumericalColumn DataMemberBinding="{Binding StadiumCapacity, StringFormat='{0:N0}'}"
HeaderText="Stadium Capacity"/>
<telerik:DataGridBooleanColumn DataMemberBinding="{Binding IsChampion, Converter={StaticResource BoolToValueConverter}}"
HeaderText="Champion"/>
<telerik:DataGridDateColumn PropertyName="Established"
HeaderText="Date Established"/>
<telerik:DataGridComboBoxColumn PropertyName="Championship"
HeaderText="Championship"
ItemsSourcePath="Championships"/>
<telerik:DataGridTemplateColumn HeaderText="Location">
<telerik:DataGridTemplateColumn.CellContentTemplate>
<DataTemplate>
<Grid>
<VerticalStackLayout InputTransparent="True">
<Label Text="{Binding Country}"
TextColor="#009688"
Margin="0, 5, 0, 5"
HorizontalOptions="Center"
VerticalTextAlignment="Center"/>
<Label Text="{Binding City}"
TextColor="#80CBC4"
HorizontalOptions="Center"
VerticalTextAlignment="Center"
FontSize="12"/>
</VerticalStackLayout>
</Grid>
</DataTemplate>
</telerik:DataGridTemplateColumn.CellContentTemplate>
</telerik:DataGridTemplateColumn>
<telerik:DataGridNumericalColumn DataMemberBinding="{Binding Path=Revenue, StringFormat='{0:C}', TargetNullValue='N/A'}"
HeaderText="Revenue (in millions)"/>
</telerik:RadDataGrid.Columns>
</telerik:RadDataGrid>
2. Add the telerik
namespace:
xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"
3. Define the Club
class:
public class Club : NotifyPropertyChangedBase
{
private string name;
private DateTime established;
private int stadiumCapacity;
private bool isChampion;
private string country;
private string city;
private string championship;
private double? revenue;
public Club(string name, DateTime established, int stadiumCapacity, string country, string city, string championship, double? revenue)
{
Name = name;
Established = established;
StadiumCapacity = stadiumCapacity;
Country = country;
City = city;
Championship = championship;
Revenue = revenue;
}
public string Name
{
get { return this.name; }
set { this.UpdateValue(ref this.name, value); }
}
public DateTime Established
{
get { return this.established; }
set { this.UpdateValue(ref this.established, value); }
}
public int StadiumCapacity
{
get { return this.stadiumCapacity; }
set { this.UpdateValue(ref this.stadiumCapacity, value); }
}
public bool IsChampion
{
get { return this.isChampion; }
set { this.UpdateValue(ref this.isChampion, value); }
}
public string Country
{
get { return this.country; }
set { this.UpdateValue(ref this.country, value); }
}
public string City
{
get { return this.city; }
set { this.UpdateValue(ref this.city, value); }
}
public string Championship
{
get { return this.championship; }
set { this.UpdateValue(ref this.championship, value); }
}
public double? Revenue
{
get { return this.revenue; }
set { this.UpdateValue(ref this.revenue, value); }
}
public List<string> Championships => new List<string> { "UEFA Champions League", "Premier League", "La Liga" };
}
4. Create an ObservableCollection
in the ViewModel
class:
public class ViewModel
{
private ObservableCollection<Club> clubs;
public ObservableCollection<Club> Clubs => clubs ?? (clubs = CreateClubs());
private ObservableCollection<Club> CreateClubs()
{
return new ObservableCollection<Club>
{
new Club("UK Liverpool ", new DateTime(1892, 1, 1), 54074, "England", "Liverpool", "Premier League", null),
new Club("Manchester Utd.", new DateTime(1878, 1, 1), 74310, "England", "Manchester", "Premier League", 594.3) { IsChampion = true },
new Club("Chelsea", new DateTime(1905, 1, 1), 42055, "England", "London","UEFA Champions League", 481.3),
new Club("Barcelona", new DateTime(1899, 1, 1), 99354, "Spain", "Barcelona", "La Liga", 540.5)
};
}
}
To learn more about defining columns and the different types of columns, you can take a look at the Columns Section.
Additional Resources
- .NET MAUI DataGrid Product Page
- .NET MAUI DataGrid Forum Page
- Telerik .NET MAUI Blogs
- Telerik .NET MAUI Roadmap