Max
Top achievements
Rank 1
Iron
I along with a few other people have made requests for an official RadGridPager for Maui and I just noticed a fresh post regarding this so wanted to post the code I have created.
This is a super simple and probably bug ridden but its working for my purposes so far.
If someone has a better implementation please post would love to use it.
1 Answer, 1 is accepted
1
Max
Top achievements
Rank 1
Iron
answered on 03 Jan 2023, 11:14 AM
| edited on 03 Jan 2023, 11:22 AM
Please note that this depends on Maui Community Toolkit
<?xml version="1.0" encoding="utf-8" ?>
<ContentView
x:Class="WebTail.Cloud.Mobile.Controls.RadGridPager"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:fa="clr-namespace:FontAwesome"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui">
<ContentView.Resources>
<ResourceDictionary>
<mct:IntToBoolConverter x:Key="IntToBoolConverter" />
</ResourceDictionary>
</ContentView.Resources>
<FlexLayout
AlignContent="SpaceAround"
AlignItems="Center"
BindingContext="{Binding Source={RelativeSource AncestorType={x:Type ContentView}}}"
HorizontalOptions="Fill"
JustifyContent="SpaceEvenly">
<telerik:RadButton
BackgroundColor="{StaticResource Primary}"
BindingContext="{Binding Source={RelativeSource AncestorType={x:Type ContentView}}}"
Command="{Binding BackCommand}"
FontFamily="FontAwesome6Solid"
Text="{x:Static fa:FontAwesomeIcons.BackwardStep}"
TextColor="{StaticResource White}" />
<Label IsVisible="{Binding TotalPages, Converter={StaticResource IntToBoolConverter}}" TextColor="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}">
<Label.Text>
<MultiBinding StringFormat="{}Page {0} of {1}">
<Binding Path="Page" />
<Binding Path="TotalPages" />
</MultiBinding>
</Label.Text>
</Label>
<telerik:RadButton
BackgroundColor="{StaticResource Primary}"
BindingContext="{Binding Source={RelativeSource AncestorType={x:Type ContentView}}}"
Command="{Binding ForwardCommand}"
FontFamily="FontAwesome6Solid"
Text="{x:Static fa:FontAwesomeIcons.ForwardStep}"
TextColor="{StaticResource White}" />
<telerik:RadButton
BackgroundColor="{StaticResource Primary}"
BindingContext="{Binding Source={RelativeSource AncestorType={x:Type ContentView}}}"
Command="{Binding RefreshCommand}"
FontFamily="FontAwesome6Solid"
Text="{x:Static fa:FontAwesomeIcons.ArrowsRotate}"
TextColor="{StaticResource White}" />
</FlexLayout>
</ContentView>
public class PageChangeEventArgs : EventArgs
{
public PageChangeEventArgs(int newPage)
{
this.NewPage = newPage;
}
public int NewPage { get; }
}
public partial class RadGridPager : ContentView
{
public event EventHandler<PageChangeEventArgs>? Back;
public event EventHandler<PageChangeEventArgs>? Forward;
public event EventHandler<EventArgs>? Refresh;
public static readonly BindableProperty PageProperty = BindableProperty.CreateAttached(nameof(Page), typeof(int), typeof(RadGridPager), 1);
public static readonly BindableProperty PageSizeProperty = BindableProperty.CreateAttached(nameof(PageSize), typeof(int), typeof(RadGridPager), 50);
public static readonly BindableProperty TotalProperty = BindableProperty.CreateAttached(nameof(Total), typeof(int), typeof(RadGridPager), 0, propertyChanged: RadGridPager.TotalPropertyChanged);
public RadGridPager()
{
InitializeComponent();
this.BackCommand = new DelegateCommand<object>(o =>
{
if (this.Page > 1)
{
this.Page--;
this.Back?.Invoke(this, new PageChangeEventArgs(this.Page));
}
});
this.ForwardCommand = new DelegateCommand<object>(o =>
{
if (this.Page < this.TotalPages)
{
this.Page++;
this.Forward?.Invoke(this, new PageChangeEventArgs(this.Page));
}
});
this.RefreshCommand = new DelegateCommand<object>(o =>
{
this.Refresh?.Invoke(this, EventArgs.Empty);
});
}
public int Page
{
get => (int)this.GetValue(PageProperty);
set => this.SetValue(PageProperty, value);
}
public int PageSize
{
get => (int)this.GetValue(PageSizeProperty);
set => this.SetValue(PageSizeProperty, value);
}
public int Total
{
get => (int)this.GetValue(TotalProperty);
set => this.SetValue(TotalProperty, value);
}
public int TotalPages => this.Total > 0 ? (int)Math.Ceiling((double)this.Total / this.PageSize) : 0;
private static void TotalPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
((RadGridPager)bindable).OnPropertyChanged(nameof(TotalPages));
}
public DelegateCommand<object> BackCommand { get; }
public DelegateCommand<object> ForwardCommand { get; }
public DelegateCommand<object> RefreshCommand { get; }
}
Usage Example:
<controls:RadGridPager
Page="{Binding Page, Mode=TwoWay}"
PageSize="{Binding PageSize}"
Total="{Binding TotalRecords}">
<controls:RadGridPager.Behaviors>
<mct:EventToCommandBehavior
Command="{Binding RefreshCommand}"
EventArgsConverter="{StaticResource GenericArgsValueConverter}"
EventName="Refresh" />
<mct:EventToCommandBehavior
Command="{Binding ForwardCommand}"
EventArgsConverter="{StaticResource GenericArgsValueConverter}"
EventName="Forward" />
<mct:EventToCommandBehavior
Command="{Binding BackCommand}"
EventArgsConverter="{StaticResource GenericArgsValueConverter}"
EventName="Back" />
</controls:RadGridPager.Behaviors>
</controls:RadGridPager>
Didi
commented on 03 Jan 2023, 11:20 AM
Telerik team
Hi Max,
Thank you for sharing the approach you have used for DataGrid paging.
Max
commented on 04 Jan 2023, 12:32 PM
Top achievements
Rank 1
Iron
No worries at all, if someone else doesn't post any code I will just mark my answer as the accepted answer in a few days.
Hanoch
commented on 11 Jan 2023, 03:39 PM
Top achievements
Rank 1
Hi Max,
Can you please share a full working sample with pager, filter on demand, and data in porting ?
Mapsui has a pager and I can share some of my own implementation details on how I folded and enhanced all the Maui-related portions into a single Maui class library.
David Pressman