RadGridPager for Maui

1 Answer 214 Views
DataGrid
Max
Top achievements
Rank 1
Iron
Max asked on 03 Jan 2023, 11:13 AM | edited on 03 Jan 2023, 11:17 AM

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.

David
Top achievements
Rank 1
Iron
commented on 12 Dec 2023, 03:08 PM

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

1 Answer, 1 is accepted

Sort by
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
Telerik team
commented on 03 Jan 2023, 11:20 AM

Hi Max,

Thank you for sharing the approach you have used for DataGrid paging.

Max
Top achievements
Rank 1
Iron
commented on 04 Jan 2023, 12:32 PM

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
Top achievements
Rank 1
commented on 11 Jan 2023, 03:39 PM

Hi Max,

Can you please share a full working sample with pager, filter on demand, and data in porting ?

Tags
DataGrid
Asked by
Max
Top achievements
Rank 1
Iron
Answers by
Max
Top achievements
Rank 1
Iron
Share this question
or