Avalonia11中自定义pagination分页组件

520 阅读2分钟

背景:

在Avalionia11中可以使用DataGrid数据表格展示数据,绑定一个可观察的集合(Observable Collection)可以很容易实现表格展示,但从官网中未找到表格分页显示的相关信息。

使用ReactiveUI MVVM模式;

鉴于不重复造轮子的想法找了找,没有找到相关的轮子,于是自己动手实现一个。

需求:

使用表格展示数据,可以上一页,下一页。

实现思路:

  1. 2个Button分别操作上一页,下一页,2个TextBlock展示当前页和总页码数;
  2. 上一页绑定Command,每次使用前PageNum先减一,同理下一页先加1;
  3. 定义分页ViewModel类,构造函数添加入参为回调表格数据;
  4. 添加按钮鼠标悬浮和离开效果;

关键代码:

<StackPanel Margin="10" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
	<Button Content="Prev" Command="{Binding PrePageCommand}" PointerEntered="Pre_Button_PointerEntered" PointerExited="Next_Button__PointerExited"/>
	<TextBlock Margin="10 0 0 0" Text="{Binding PageNum}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
	<TextBlock Text="/" HorizontalAlignment="Center" VerticalAlignment="Center"/>
	<TextBlock Margin="0 0 10 0" Text="{Binding PageCount}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
	<Button Content="Next" Command="{Binding NextPageCommand}" PointerEntered="Pre_Button_PointerEntered" PointerExited="Next_Button__PointerExited"/>
</StackPanel>

public partial class PagedView : UserControl
{
    public PagedView()
    {
        InitializeComponent();
    }
    public void Pre_Button_PointerEntered(object sender, PointerEventArgs e)
    {
        var button = (Button)sender;
        button.Cursor = new Cursor(StandardCursorType.Hand);
    }
    public void Next_Button__PointerExited(object sender, PointerEventArgs e)
    {
        var button = (Button)sender;
        button.Cursor = new Cursor(StandardCursorType.None);
    }
}

public class PagedViewModel : ViewModelBase
{
    private int _pageSize = 10;
    private int _pageNum = 1;
    public long Total { get; set; } = 0;
    public Action<int> callBack { get; set; }

    public PagedViewModel(Action<int> callBack)
    {
        PrePageCommand = ReactiveCommand.Create(PrePage);
        NextPageCommand = ReactiveCommand.Create(NextPage);
        JumpPageCommand = ReactiveCommand.Create(() => { Debug.WriteLine("JumpPageCommand Not implemented yet ..."); });
        this.callBack = callBack;
    }
    public int PageSize
    {
        get => _pageSize;
        set => this.RaiseAndSetIfChanged(ref _pageSize, value);
    }
    public int PageNum
    {
        get => _pageNum;
        set => this.RaiseAndSetIfChanged(ref _pageNum, value);
    }
    public int PageCount => (int)Math.Ceiling(Total / (double)PageSize);

    public ReactiveCommand<Unit, Unit> PrePageCommand { get; }
    public ReactiveCommand<Unit, Unit> NextPageCommand { get; }
    public ReactiveCommand<Unit, Unit> JumpPageCommand { get; }
    public void PrePage()
    {
        if (PageNum > 1)
        {
            --PageNum;
        }
        callBack.Invoke(PageNum);
    }

    public void NextPage()
    {
        if (PageNum < PageCount)
        {
            ++PageNum;
        }
        callBack.Invoke(PageNum);
    }
}

效果展示:

使用方法:

1.示例如何使用分页组件,绑定DataContext.

xmlns:components="clr-namespace:MirrorFiledControlFront.Views.Components"
    
    <DataGrid ItemsSource="{Binding TempSensorDatas}"
GridLinesVisibility="Horizontal"
BorderThickness="1" BorderBrush="Black">
	<DataGrid.Columns>
		<DataGridTextColumn Header="列1" Binding="{Binding tempSensorNo}"/>
		<DataGridTextColumn Header="列2" Binding="{Binding temp}"/>
		<DataGridTextColumn Header="列3" Binding="{Binding createTime}"/>
	</DataGrid.Columns>
</DataGrid>
<components:PagedView DataContext="{Binding PageQueryParam}"/>

2.要引入分页组件的ViewModel中定义PagedViewModel

private PagedViewModel _pageQueryParam;
public PagedViewModel PageQueryParam
{
    get => _pageQueryParam;
    set => this.RaiseAndSetIfChanged(ref _pageQueryParam, value);
}
// 引入组件的构造方法
public ViewModel()
{
    //requestApi为请求数据的方法
    PageQueryParam = new PagedViewModel(requestApi);
}

深潜:

  1. 轮子的多少很大影响后期开发的工作量,技术选型的时候要多注意这个了,关注技术栈的生态很重要;
  2. 有的时候你以为的并不是你以为的,在这次桌面软件使用Avalonia开发时体会很深刻。

总结:

一个小组件但是又是必须的,可以拿来即用,基本贴出了全部代码。

还造了一个抽屉组件,原本以为SuKiUI中都有,结果竟然没有,计划下次分享。

本文完。