DataGrid

DataGrid displays sets of data across rows and columns.

Getting Started

DataGrid is included in the UraniumUI.Material.Controls namespace. You can add it to your XAML like this:

xmlns:controls="clr-namespace:UraniumUI.Material.Controls;assembly=UraniumUI.Material"

DataGrid can't be used standalone without csharp code. You need to bind some data to ItemsSource property.

public class MainPageViewModel : BindableObject
{
	static Random random = new();
	public ObservableCollection<Student> Items { get; } = new();
	public MainPageViewModel()
	{
		for (int i = 0; i < 10; i++)
		{
			Items.Add(new Student
			{
				Id = i,
				Name = "Person " + i,
				Age = random.Next(14, 85),
			});
		}
    }
	public class Student
	{
		public int Id { get; set; }
		public string Name { get; set; }
		public int Age { get; set; }
	}
}

Then use it in XAML like this:

 <controls:DataGrid ItemsSource="{Binding Items}" UseAutoColumns="True" Margin="30" />
Light - Desktop Dark - Android Light - iOS
MAUI datagrid

Customizations

CellItemTemplate

You can customize the cell item template by using CellItemTemplate property. It is a DataTemplate that is used to render each cell item. You can use DataGridCellItem as the root element of the template. It has a DataContext of the cell item. You can use Binding to bind the properties of the cell item.

You can use any property of CellBindingContext object inside DataTemplate.

<material:DataGrid ItemsSource="{Binding Items}" UseAutoColumns="True" HorizontalOptions="Center">
	<material:DataGrid.CellItemTemplate>
		<DataTemplate>
			<VerticalStackLayout VerticalOptions="Center">
				<Label Text="{Binding Value}" TextColor="Red" />
				<Label Text="{Binding Row,StringFormat='Row:{0}'}" />
				<Label Text="{Binding Column,StringFormat='Column:{0}'}" />                                
			</VerticalStackLayout>
		</DataTemplate>
	</material:DataGrid.CellItemTemplate>
</material:DataGrid>

MAUI DataGrid Cell Item Template

Columns

Auto Columns

Columns are automatically detected by DataGrid when UseAutoColumns property is set as True. It uses reflection to get properties of the data source. You can use DataAnnosations attributes to define Title of column in auto mode. Adding [DisplayName] attribute to the property will define the title of the column.

[DisplayName("Identity Number")]
public int Id { get; set; }

MAUI Datagrid header

Custom Columns

You can also define columns manually by adding DataGridColumn to Columns property of DataGrid. UseAutoColumns must be false. You can remove it from XAML. Its default value is false.

<material:DataGrid ItemsSource="{Binding Items}" HorizontalOptions="Center" Margin="30">
	<material:DataGrid.Columns>
		<material:DataGridColumn PropertyName="Name" Title="Student Name"/>

		<material:DataGridColumn PropertyName="Age" Title="Student Age"/>

		<material:DataGridColumn PropertyName="Id" Title="Identity" />
	</material:DataGrid.Columns>
</material:DataGrid>

An ItemTemplate can be defined for each column via using CellItemTemplate property of DataGridColumn class.

<material:DataGrid ItemsSource="{Binding Items}" HorizontalOptions="Center" Margin="30">
	<material:DataGrid.Columns>
		<material:DataGridColumn PropertyName="Name" Title="Student Name"/>

		<material:DataGridColumn PropertyName="Age" Title="Student Age">
			<material:DataGridColumn.CellItemTemplate>
				<DataTemplate>
					<Frame BorderColor="Blue" BackgroundColor="Transparent" Padding="5" >
						<Label Text="{Binding Value}" TextColor="Blue" />
					</Frame>
				</DataTemplate>
			</material:DataGridColumn.CellItemTemplate>
		</material:DataGridColumn>

		<material:DataGridColumn PropertyName="Id" Title="Identity" />

	</material:DataGrid.Columns>
</material:DataGrid>

MAUI DataGrid Custom Columns

Columns are not limited to the properties of the data source. You can also use custom columns without any property mapping. You can use CellItemTemplate to define the content of the column. That column will be rendered and CellBindingContext will be passed to the template. You can use Data property of CellBindingContext to get the data of current row.

<material:DataGrid ItemsSource="{Binding Items}" HorizontalOptions="Center" Margin="30">
	<material:DataGrid.Columns>
		<material:DataGridColumn PropertyName="Name" Title="Student Name"/>

		<!-- This is a custom column without a property. -->
		<material:DataGridColumn Title="Actions" >
			<material:DataGridColumn.CellItemTemplate>
				<DataTemplate>
					<Button Text="Remove"
							Command="{Binding Source={x:Reference page}, Path=BindingContext.RemoveItemCommand}"
							CommandParameter="{Binding Data}"/>
				</DataTemplate>
			</material:DataGridColumn.CellItemTemplate>
		</material:DataGridColumn>

	</material:DataGrid.Columns>
</material:DataGrid>

MAUI DataGrid Custom Columns

Column Width

Column width can be defined by using Width property of DataGridColumn class. It can be set as Auto, Star or a custom value. Its type is GridLength and it'll be passed as parameter to ColumnDefinition. Auto is the default value. It will be calculated automatically. Star will take the remaining space of the grid. You can also set a custom value. It can be a double or a GridLength.

<material:DataGrid ItemsSource="{Binding Items}" HorizontalOptions="Center" Margin="30">
	<material:DataGrid.Columns>

		<material:DataGridColumn PropertyName="Name" Title="Student Name" Width="Auto"/>

		<material:DataGridColumn PropertyName="Age" Title="Student Age" Width="*"/>

		<material:DataGridColumn PropertyName="Id" Title="Identity" Width="100"/>

	</material:DataGrid.Columns>
</material:DataGrid>

MAUI DataGrid Column Width

TitleView

You can define a custom view for the header of the column by using TitleView property of DataGridColumn class. It is a View that will be rendered as the header of the column. You can use Binding to bind the properties of the column. Since it's a regular cell of the DataGrid its binding context is CellBindingContext.

 <material:DataGrid ItemsSource="{Binding Items}">
	<material:DataGrid.Columns>
		<material:DataGridColumn PropertyName="Id">
			<material:DataGridColumn.TitleView>
				<Image Source="{FontImageSource FontFamily=MaterialRegular, Glyph={x:Static m:MaterialRegular.Fingerprint}, Color={StaticResource Primary}}" />
			</material:DataGridColumn.TitleView>
		</material:DataGridColumn>

		<material:DataGridColumn PropertyName="Name">
			<material:DataGridColumn.TitleView>
				<Image Source="{FontImageSource FontFamily=MaterialRegular, Glyph={x:Static m:MaterialRegular.Badge}, Color={StaticResource Primary}}" />
			</material:DataGridColumn.TitleView>
		</material:DataGridColumn>

		<material:DataGridColumn PropertyName="Age">
			<material:DataGridColumn.TitleView>
				<Image Source="{FontImageSource FontFamily=MaterialRegular, Glyph={x:Static m:MaterialRegular.Calendar_today}, Color={StaticResource Primary}}" />
			</material:DataGridColumn.TitleView>
		</material:DataGridColumn>
	</material:DataGrid.Columns>
</material:DataGrid>
Light Dark
MAUI DataGrid TitleView MAUI DataGrid TitleView

TitleTemplate

You can define a custom template for the title of the DataGrid by using TitleTemplate property. This is still a table cell and its binding context will be CellBindingContext. You can use Value property of CellBindingContext to get the title of the column.

<material:DataGrid ItemsSource="{Binding Items}" HorizontalOptions="Center" Margin="30">
	<material:DataGrid.TitleTemplate>
		<DataTemplate>
			<Label Text="{Binding Value}" FontSize="Big" TextColor="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
		</DataTemplate>
	</material:DataGrid.TitleTemplate>
</material:DataGrid>
Light Dark
MAUI DataGrid Title Template MAUI DataGrid Title Template

EmptyView

You can define a view to be shown when the data source is empty. It can be defined by using EmptyView property of DataGrid.

<material:DataGrid ItemsSource="{Binding Items}">
	<material:DataGrid.EmptyView>
		<VerticalStackLayout Margin="80,20">
			<Image
				WidthRequest="40"
				HeightRequest="40"
				HorizontalOptions="Center"
				VerticalOptions="Center"
				Source="{FontImageSource FontFamily=MaterialOutlined, Glyph={x:Static m:MaterialOutlined.Backup_table}, Color={AppThemeBinding Light={StaticResource OnSurface}, Dark={StaticResource OnSurfaceDark}}}"/>
			<Label Text="No data available..." HorizontalOptions="Center"/>
		</VerticalStackLayout>
	</material:DataGrid.EmptyView>
</material:DataGrid>

MAUI DataGrid EmptyView

Selection

DataGrid supports multiple row selection. You can add DataGridSelectionColumn column to enable selection. Selected Items can be accessed via SelectedItems property of DataGrid. You can bind it to a property of your ViewModel.

<material:DataGrid ItemsSource="{Binding Items}" SelectedItems="{Binding SelectedItems}">
	<material:DataGrid.Columns>
		<material:DataGridSelectionColumn />
		<material:DataGridColumn PropertyName="Id" Title="Identity" />
		<material:DataGridColumn PropertyName="Name" Title="Name" />
		<material:DataGridColumn PropertyName="Age" Title="Age" />
	</material:DataGrid.Columns>
</material:DataGrid>
Dark - Desktop Light - Mobile
MAUI DataGrid Selection MAUI DataGrid Selection android

SelectedItems can be handled with ObservableCollection over IList interface. So you can use INotifyCollectionChanged to handle changes in selection. The bound list will be automatically updated. You don't need to register to CollectionChanged event of SelectedItems property.

public class MainViewModel
{
    public ObservableCollection<Student> Items { get; set; }
    public ObservableCollection<Student> SelectedItems { get; set; } = new ObservableCollection<Student>();
    public ICommand RemoveSelectedCommand { get; set; }
    
    public MainViewModel()
    {
        Items = new ObservableCollection<Student>(GetStudents());
        
        RemoveSelectedCommand = new Command(() =>
        {
            foreach (var item in SelectedItems)
            {
                Items.Remove(item);
            }
        });
    }
}
<StackLayout>
	<Button Text="Delete Selected" Command="{Binding RemoveSelectedCommand}" />
	<material:DataGrid ItemsSource="{Binding Items}" SelectedItems="{Binding SelectedItems}">
		<material:DataGrid.Columns>
			<material:DataGridSelectionColumn />
			<material:DataGridColumn PropertyName="Id" Title="Identity" />
			<material:DataGridColumn PropertyName="Name" Title="Name" />
			<material:DataGridColumn PropertyName="Age" Title="Age" />
		</material:DataGrid.Columns>
	</material:DataGrid>
</StackLayout>

MAUI DataGrid Selection Deletion

Tips

You can place an activity indicator inside the DataGrid to show loading state if you make a network call to get data.

<material:DataGrid ItemsSource="{Binding Items}" HorizontalOptions="Center">
	<ActivityIndicator IsRunning="{Binding IsBusy}" Margin="40" />
</material:DataGrid>

MAUI DataGrid Loading

CellBindingContext

CellBindingContext is an object that is used as the DataContext of the CellItemTemplate. It has the following properties:

Property Description
Data The data of the cell item.
Column The column number of the cell item.
Row The row number of the cell item.
Value The value of the cell item. (You can bind it to the label directly)
IsSelected Indicates whether the cell item is selected or not.

DataGridColumn

DataGridColumn is a class that is used to define a column of DataGrid. It has the following properties:

  • Title: It's used in header of the column.
  • CellItemTemplate: It's used to define the template of the cell item of the column.
  • PropertyName: It's used to define the property of the data source that is used to get the value of the cell item. You can leave it empty if you want to use a custom column.
In this document