背景:
在Avalionia11中可以使用DataGrid数据表格展示数据,绑定一个可观察的集合(Observable Collection)可以很容易实现表格展示,但从官网中未找到表格分页显示的相关信息。
使用ReactiveUI MVVM模式;
鉴于不重复造轮子的想法找了找,没有找到相关的轮子,于是自己动手实现一个。
需求:
使用表格展示数据,可以上一页,下一页。
实现思路:
- 2个Button分别操作上一页,下一页,2个TextBlock展示当前页和总页码数;
- 上一页绑定Command,每次使用前PageNum先减一,同理下一页先加1;
- 定义分页ViewModel类,构造函数添加入参为回调表格数据;
- 添加按钮鼠标悬浮和离开效果;
关键代码:
<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);
}
深潜:
- 轮子的多少很大影响后期开发的工作量,技术选型的时候要多注意这个了,关注技术栈的生态很重要;
- 有的时候你以为的并不是你以为的,在这次桌面软件使用Avalonia开发时体会很深刻。
总结:
一个小组件但是又是必须的,可以拿来即用,基本贴出了全部代码。
还造了一个抽屉组件,原本以为SuKiUI中都有,结果竟然没有,计划下次分享。
本文完。