.NET MAUI DataGrid Columns Reordering
The .NET MAUI DataGrid exposes a reordering feature allowing the user to drag and drop columns and change their order.
The following properties are relted to the reordering feature:
-
CanUserReorderColumns
(bool
)—Defines whether the user can reorder theDataGridColumns
. The default value istrue
. -
ColumnReorderIndicatorTemplate
(DataTemplate
)—Defines the template that presents the indicator that is displayed between two columns during reordering. -
ColumnHeaderDragVisualTemplate
(DataTemplate
)—Specifies the template that presents the drag visual of the dragged column header.
Events
The DataGrid exposes the following events related to the reordering operation:
-
ColumnReorderStarting
—Raised when the user starts to drag a column to reorder it. TheColumnReorderStarting
event handler receives the following parameters:- A
sender
argument, which is of typeobject
, but can be cast to theRadDataGrid
type. - A
ColumnReorderStartingEventArgs
object, which has a reference to the following properties:-
Column
(DataGridColumn
)—Gets the column that will be reordered. -
Index
(int
) —Gets the index of the column that will be reordered. TheIndex
is the index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofColumn.IsFrozen
. -
Cancel
(bool
)—Defines a value indicating whether the reordering operation is canceled.
-
- A
-
ColumnReordering
—Raised continuously while the column is being dragged. TheColumnReordering
event handler receives the following parameters:- A
sender
argument, which is of typeobject
, but can be cast to theRadDataGrid
type. - A
ColumnReorderingEventArgs
object, which has a reference to the following properties:-
Column
(DataGridColumn
)—Gets the column that will be reordered. -
OldIndex
(int
) —Gets the initial index of the column that is being reordered. TheOldIndex
is the old index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofColumn.IsFrozen
. -
NewIndex
(int
) —Gets the new potential index of the column that is being reordered. TheNewIndex
is the new index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofNewIsFrozen
. -
NewIsFrozen
(bool
)—Gets the new potentialTelerik.Maui.Controls.DataGrid.DataGridColumn.IsFrozen
value of the column that is being reordered. -
CanDrop
(bool
)—Defines a value indicating whether dropping the column at this specific location is allowed. The default value istrue
.
-
- A
-
ColumnReorderCompleting
—Raised when the user drops the column. This doesn't mean the column is reordered. TheColumnReorderCompleting
event handler receives the following parameters:- A
sender
argument, which is of typeobject
, but can be cast to theRadDataGrid
type. - A
ColumnReorderCompletingEventArgs
object, which has a reference to the following properties:-
Column
(DataGridColumn
)—Gets the column that is being reordered. -
OldIndex
(int
) —Gets the initial index of the column that is being reordered. TheOldIndex
is the old index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofColumn.IsFrozen
. -
NewIndex
(int
) —Gets the new potential index of the column that is being reordered. TheNewIndex
is the new index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofNewIsFrozen
. -
NewIsFrozen
(bool
)—Gets the new potentialTelerik.Maui.Controls.DataGrid.DataGridColumn.IsFrozen
value of the column that is being reordered. -
IsDropAllowed
(bool
)—Gets a value that indicates whether the column was dropped at a valid location. A valid location means that the column has changed its index and/or the value of itsIsFrozen
property and the drop at this location was not forbidden by setting theTelerik.Maui.Controls.DataGrid.ColumnReorderingEventArgs.CanDrop
property of theTelerik.Maui.Controls.DataGrid.ColumnReorderingEventArgs
tofalse
. The default value istrue
. -
Cancel
(bool
)—Defines a value indicating whether the reordering operation is canceled.
-
- A
-
ColumnReordered
—Raised when a column has been successfully reordered. TheColumnReordered
event handler receives the following parameters:- A
sender
argument which is of typeobject
, but can be cast to theRadDataGrid
type. - A
ColumnReorderCompletingEventArgs
object, which has a reference to the following properties:-
Column
(DataGridColumn
)—Gets the column that has been reordered. -
OldIndex
(int
) —Gets the initial index of the column that has been reordered. TheOldIndex
is the old index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofOldIsFrozen
. -
OldIsFrozen
(bool
)—Gets the initialTelerik.Maui.Controls.DataGrid.DataGridColumn.IsFrozen
value of the column that has been reordered. -
NewIndex
(int
) —Gets the new index of the column that has been reordered. TheNewIndex
is the new index of the item inside theFrozenColumns
orUnfrozenColumns
collection, depending on the value ofColumn.IsFrozen
.
-
- A
Example with Reorder Columns and Events
The following example shows how to bind the CanUserReorderColumns
using MVVM and a sample scenario with the reordering events.
1. Create a sample model:
public class PersonDetails
{
public string Name { get; set; }
public int Age { get; set; }
public double Weight { get; set; }
public Gender Gender { get; set; }
}
2. Create a ViewModel
:
public class ViewModel : NotifyPropertyChangedBase
{
private bool isReorderingEnabled = true;
public ViewModel()
{
this.Data = new ObservableCollection<PersonDetails>
{
new PersonDetails { Name = "Juan", Age = 21, Gender = Gender.Male, Weight = 94.2 },
new PersonDetails { Name = "Larry", Age = 22, Gender = Gender.Male, Weight = 68.9 },
new PersonDetails { Name = "Tiffany", Age = 34, Gender = Gender.Female, Weight = 83 },
new PersonDetails { Name = "Sebastian", Age = 16, Gender = Gender.Other, Weight = 72 },
new PersonDetails { Name = "Bojidara", Age = 42, Gender = Gender.Female, Weight = 52 },
};
}
public ObservableCollection<PersonDetails> Data { get; set; }
public bool IsReorderingEnabled
{
get => this.isReorderingEnabled;
set => this.UpdateValue(ref this.isReorderingEnabled, value);
}
}
3. Define the DataGrid and a control which will change the CanUserReorderColumns
value in XAML:
<Grid RowDefinitions="Auto, *">
<Grid ColumnDefinitions="Auto, Auto" Margin="0, 0, 0, 10">
<Label Text="Enable Column Reordering: " VerticalOptions="Center"/>
<Switch Grid.Column="1"
IsToggled="{Binding IsReorderingEnabled, Mode=TwoWay}"
VerticalOptions="Center"
HorizontalOptions="End"/>
</Grid>
<telerik:RadDataGrid x:Name="dataGrid"
Grid.Row="1"
AutoGenerateColumns="False"
ItemsSource="{Binding Data}"
CanUserReorderColumns="{Binding IsReorderingEnabled}"
ColumnReorderStarting="OnColumnReorderStarting"
ColumnReordering="OnColumnReordering"
ColumnReorderCompleting="OnColumnReorderCompleting"
ColumnReordered="OnColumnReordered">
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn PropertyName="Name" IsFrozen="True" />
<telerik:DataGridNumericalColumn PropertyName="Age" />
<telerik:DataGridComboBoxColumn PropertyName="Gender" />
<telerik:DataGridNumericalColumn PropertyName="Weight" />
</telerik:RadDataGrid.Columns>
</telerik:RadDataGrid>
</Grid>
4. Add the telerik
namespace:
xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"
5. Sample implementation in the reordering event:
private void OnColumnReorderStarting(object sender, Telerik.Maui.Controls.DataGrid.ColumnReorderStartingEventArgs e)
{
if (e.Column.IsFrozen)
{
e.Cancel = true;
Application.Current.MainPage.DisplayAlert("", "Reorder is canceled because the column is Frozen", "OK");
}
}
private void OnColumnReordering(object sender, Telerik.Maui.Controls.DataGrid.ColumnReorderingEventArgs e)
{
// add your logic here
}
private void OnColumnReorderCompleting(object sender, Telerik.Maui.Controls.DataGrid.ColumnReorderCompletingEventArgs e)
{
if (!e.Column.IsFrozen && e.NewIsFrozen)
{
e.Cancel = true;
Application.Current.MainPage.DisplayAlert("", $"Cannot add the {(e.Column as DataGridTypedColumn).HeaderText} column to the frozen area", "OK");
}
}
private void OnColumnReordered(object sender, Telerik.Maui.Controls.DataGrid.ColumnReorderedEventArgs e)
{
Application.Current.MainPage.DisplayAlert("", $"{(e.Column as DataGridTypedColumn).HeaderText} column was reordered!", "OK");
}
The result on mobile:
Example with Indicator Template when Reordering Columns
The following example shows how to define the ColumnReorderIndicatorTemplate
in XAML:
1. Define the DataTemplate
for the Indicator in the Resources of the page:
<DataTemplate x:Key="ReorderIndicatorTemplate">
<telerik:RadBorder BackgroundColor="#80CBC4"
WidthRequest="4"
HorizontalOptions="Start"
InputTransparent="True" />
</DataTemplate>
2. Define the DataTemplate
for the header drag template in the Resources of the page:
<DataTemplate x:Key="HeaderDragTemplate">
<telerik:RadBorder BackgroundColor="#80CBC4"
CornerRadius="2"
MinimumWidthRequest="{Binding ActualWidth}">
<Label Text="{Binding HeaderText, FallbackValue='dragging...'}"
TextColor="#000000"
Margin="10, 8" />
</telerik:RadBorder>
</DataTemplate>
3. Define the DataTemplate
for the group item template in the Resources of the page:
<Style x:Key="ButtonStyle_XClose" TargetType="telerik:RadButton">
<Setter Property="Text" Value="✕" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="{OnPlatform MacCatalyst=18, WinUI=14, iOS=12, Android=10}" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="WidthRequest" Value="{OnPlatform Default=36, Android=26, iOS=26}" />
<Setter Property="HeightRequest" Value="{OnPlatform Default=16, Android=30, iOS=30}" />
<Setter Property="BorderWidth" Value="0" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="TextColor" Value="#000000" />
<Setter Property="Padding" Value="0" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="2, 0" />
</Style>
<DataTemplate x:Key="GroupingPanelItemTemplate">
<telerik:RadBorder BorderColor="#80CBC4"
BorderThickness="{OnPlatform Default=0, iOS=1, Android=1}"
Margin="{OnPlatform Default='0, 2', Android='0, 4, 4, 4'}"
CornerRadius="2">
<Grid>
<telerik:RadBorder BackgroundColor="#80CBC4"
Opacity="{OnIdiom Desktop=1, Phone=0.7}" />
<HorizontalStackLayout>
<Label Text="{Binding DisplayContent}"
TextColor="#000000"
FontSize="{OnPlatform Android=14, iOS=17, MacCatalyst=Default, WinUI=14}"
VerticalOptions="Center"
Margin="10, 0, 2, 0" />
<telerik:RadButton Command="{Binding RemoveCommand, Source={RelativeSource AncestorType={Type telerik:DataGridGroupingPanel}}}"
CommandParameter="{Binding}"
Style="{StaticResource ButtonStyle_XClose}" />
</HorizontalStackLayout>
</Grid>
</telerik:RadBorder>
</DataTemplate>
4. Define the properties in the DataGrid:
<telerik:RadDataGrid x:Name="dataGrid"
UserGroupMode="Enabled"
ItemsSource="{Binding Data}"
CanUserReorderColumns="True"
ColumnHeaderDragVisualTemplate="{StaticResource HeaderDragTemplate}"
GroupingPanelItemTemplate="{StaticResource GroupingPanelItemTemplate}"
ColumnReorderIndicatorTemplate="{StaticResource ReorderIndicatorTemplate}">
<telerik:RadDataGrid.BindingContext>
<local:ViewModel />
</telerik:RadDataGrid.BindingContext>
</telerik:RadDataGrid>
5. Add the telerik
namespace:
xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"
6. Define sample data:
public class PersonDetails
{
public string Name { get; set; }
public int Age { get; set; }
public double Weight { get; set; }
public Gender Gender { get; set; }
}
7. Define a sample ViewModel
:
public class ViewModel : NotifyPropertyChangedBase
{
private bool isReorderingEnabled = true;
public ViewModel()
{
this.Data = new ObservableCollection<PersonDetails>
{
new PersonDetails { Name = "Juan", Age = 21, Gender = Gender.Male, Weight = 94.2 },
new PersonDetails { Name = "Larry", Age = 22, Gender = Gender.Male, Weight = 68.9 },
new PersonDetails { Name = "Tiffany", Age = 34, Gender = Gender.Female, Weight = 83 },
new PersonDetails { Name = "Sebastian", Age = 16, Gender = Gender.Other, Weight = 72 },
new PersonDetails { Name = "Bojidara", Age = 42, Gender = Gender.Female, Weight = 52 },
};
}
public ObservableCollection<PersonDetails> Data { get; set; }
public bool IsReorderingEnabled
{
get => this.isReorderingEnabled;
set => this.UpdateValue(ref this.isReorderingEnabled, value);
}
}
The result on mobile:
For the runnable DataGrid Drag Templates example, see the SDKBrowser Demo Application and go to DataGrid > Columns.