wpf实现datagrid/listview分页控件(转)(代码片段)

lizhongzhongy lizhongzhongy     2022-12-21     450

关键词:

 

在WPF中,通常会选用DataGrid/ListView进行数据展示,如果数据量不多,可以直接一个页面显示出来。如果数据量很大,2000条数据,一次性显示在一个页面中,不仅消耗资源,而且用户体验也很糟糕。这篇博客将介绍如何创建一个分页控件。

为了简单起见,这个分页控件目前只有 首页/上一页/下一页/末页/总页数/第几页 等功能。实现思路,首页/上一页/下一页/末页 这四个通过路由事件来实现,在使用时可以使用命令进行绑定,或者直接使用均可。总页数和第几页通过依赖属性来实现,使用时将页数进行绑定显示即可。示例代码如下:

Pager控件:

技术图片
    <UserControl.Resources>
        <Style TargetType="x:Type Button">
            <Setter Property="Width" Value="22"/>
            <Setter Property="Height" Value="22"/>
        </Style>
    </UserControl.Resources>
    <Grid>
        <StackPanel Orientation="Horizontal">
            <Button x:Name="FirstPageButton" Margin="5,0" Click="FirstPageButton_Click">
                <Path Width="7" Height="10" Data="M0,0L0,10 M0,5L6,2 6,8 0,5" Stroke="Black" StrokeThickness="1" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" />
            </Button>
            <Button x:Name="PreviousPageButton" Margin="0,0,5,0" Click="PreviousPageButton_Click">
                <Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" />
            </Button>
            <TextBlock VerticalAlignment="Center">
                <Run Text="第"/>
                <Run x:Name="rCurrent" Text="0"/>
                <Run Text="页"/>
            </TextBlock>
            <Button Margin="5,0" x:Name="NextPageButton" Click="NextPageButton_Click">
                <Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Path.RenderTransform>
                        <RotateTransform Angle="180" CenterX="4" CenterY="4" />
                    </Path.RenderTransform>
                </Path>
            </Button>
            <Button Margin="0,0,5,0" x:Name="LastPageButton" Click="LastPageButton_Click">
                <Path x:Name="MainPath" Width="7" Height="10" Data="M0,0L0,10 M0,5 L6,2 6,8 0,5" Stroke="Black" StrokeThickness="1" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Path.RenderTransform>
                        <RotateTransform Angle="180" CenterX="3" CenterY="5" />
                    </Path.RenderTransform>
                </Path>
            </Button>
            <TextBlock VerticalAlignment="Center">
                <Run Text="共"/>
                <Run x:Name="rTotal" Text="0"/>
                <Run Text="页"/>
            </TextBlock>
        </StackPanel>     
    </Grid>
技术图片

C#:

技术图片 View Code

在MainWindow中,
XAML:

技术图片
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <DataGrid Grid.Row="0" ItemsSource="Binding FakeSource" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Item Id" Binding="Binding Id" Width="80"/>
                <DataGridTextColumn Header="Item Name" Binding="Binding ItemName" Width="180"/>
            </DataGrid.Columns>
        </DataGrid>

        <local:Pager TotalPage="Binding TotalPage"
                     CurrentPage="Binding CurrentPage, Mode=TwoWay" 
                     HorizontalAlignment="Center"
                     Grid.Row="1">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="FirstPage">
                    <i:InvokeCommandAction Command="Binding FirstPageCommand" />
                </i:EventTrigger>
                <i:EventTrigger EventName="PreviousPage">
                    <i:InvokeCommandAction Command="Binding PreviousPageCommand"/>
                </i:EventTrigger>
                <i:EventTrigger EventName="NextPage">
                    <i:InvokeCommandAction Command="Binding NextPageCommand" />
                </i:EventTrigger>
                <i:EventTrigger EventName="LastPage">
                    <i:InvokeCommandAction Command="Binding LastPageCommand"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </local:Pager>
    </Grid>
技术图片

MainViewModel类:

技术图片

public class MainViewModel : ViewModel

private ICommand _firstPageCommand;

public ICommand FirstPageCommand

get

return _firstPageCommand;

set

_firstPageCommand = value;

private ICommand _previousPageCommand;

public ICommand PreviousPageCommand

get

return _previousPageCommand;

set

_previousPageCommand = value;

private ICommand _nextPageCommand;

public ICommand NextPageCommand

get

return _nextPageCommand;

set

_nextPageCommand = value;

private ICommand _lastPageCommand;

public ICommand LastPageCommand

get

return _lastPageCommand;

set

_lastPageCommand = value;

private int _pageSize;

public int PageSize

get

return _pageSize;

set

if(_pageSize != value)

_pageSize = value;
OnPropertyChanged("PageSize");


private int _currentPage;

public int CurrentPage

get

return _currentPage;

set

if(_currentPage != value)

_currentPage = value;
OnPropertyChanged("CurrentPage");


private int _totalPage;

public int TotalPage

get

return _totalPage;

set

if(_totalPage != value)

_totalPage = value;
OnPropertyChanged("TotalPage");


private ObservableCollection<FakeDatabase> _fakeSoruce;

public ObservableCollection<FakeDatabase> FakeSource

get

return _fakeSoruce;

set

if(_fakeSoruce != value)

_fakeSoruce = value;
OnPropertyChanged("FakeSource");


private List<FakeDatabase> _source;

public MainViewModel()

_currentPage = 1;

_pageSize = 20;

FakeDatabase fake = new FakeDatabase();

_source = fake.GenerateFakeSource();

_totalPage = _source.Count / _pageSize;

_fakeSoruce = new ObservableCollection<FakeDatabase>();

List<FakeDatabase> result = _source.Take(20).ToList();

_fakeSoruce.Clear();

_fakeSoruce.AddRange(result);

_firstPageCommand = new DelegateCommand(FirstPageAction);

_previousPageCommand = new DelegateCommand(PreviousPageAction);

_nextPageCommand = new DelegateCommand(NextPageAction);

_lastPageCommand = new DelegateCommand(LastPageAction);

private void FirstPageAction()

CurrentPage = 1;

var result = _source.Take(_pageSize).ToList();

_fakeSoruce.Clear();

_fakeSoruce.AddRange(result);

private void PreviousPageAction()

if(CurrentPage == 1)

return;

List<FakeDatabase> result = new List<FakeDatabase>();

if(CurrentPage == 2)

result = _source.Take(_pageSize).ToList();

else

result = _source.Skip((CurrentPage - 2) * _pageSize).Take(_pageSize).ToList();

_fakeSoruce.Clear();

_fakeSoruce.AddRange(result);

CurrentPage--;

private void NextPageAction()

if(CurrentPage == _totalPage)

return;

List<FakeDatabase> result = new List<FakeDatabase>();

result = _source.Skip(CurrentPage * _pageSize).Take(_pageSize).ToList();

_fakeSoruce.Clear();

_fakeSoruce.AddRange(result);

CurrentPage++;

private void LastPageAction()

CurrentPage = TotalPage;

int skipCount = (_totalPage - 1) * _pageSize;
int takeCount = _source.Count - skipCount;

var result = _source.Skip(skipCount).Take(takeCount).ToList();

_fakeSoruce.Clear();

_fakeSoruce.AddRange(result);

技术图片
public class MainViewModel : ViewModel
    
        private ICommand _firstPageCommand;

        public ICommand FirstPageCommand
        
            get
            
                return _firstPageCommand;
            

            set
            
                _firstPageCommand = value;
            
        

        private ICommand _previousPageCommand;

        public ICommand PreviousPageCommand
        
            get
            
                return _previousPageCommand;
            

            set
            
                _previousPageCommand = value;
            
        

        private ICommand _nextPageCommand;

        public ICommand NextPageCommand
        
            get
            
                return _nextPageCommand;
            

            set
            
                _nextPageCommand = value;
            
        

        private ICommand _lastPageCommand;

        public ICommand LastPageCommand
        
            get
            
                return _lastPageCommand;
            

            set
            
                _lastPageCommand = value;
            
        

        private int _pageSize;

        public int PageSize
        
            get
            
                return _pageSize;
            
            set
            
                if(_pageSize != value)
                
                    _pageSize = value;
                    OnPropertyChanged("PageSize");
                
            
        

        private int _currentPage;

        public int CurrentPage
        
            get
            
                return _currentPage;
            

            set
            
                if(_currentPage != value)
                
                    _currentPage = value;
                    OnPropertyChanged("CurrentPage");
                
            
        

        private int _totalPage;

        public int TotalPage
        
            get
            
                return _totalPage;
            

            set
            
                if(_totalPage != value)
                
                    _totalPage = value;
                    OnPropertyChanged("TotalPage");
                
            
        

        private ObservableCollection<FakeDatabase> _fakeSoruce;

        public ObservableCollection<FakeDatabase> FakeSource
        
            get
            
                return _fakeSoruce;
            
            set
            
                if(_fakeSoruce != value)
                
                    _fakeSoruce = value;
                    OnPropertyChanged("FakeSource");
                
            
        

        private List<FakeDatabase> _source;

        public MainViewModel()
        
            _currentPage = 1;

            _pageSize = 20;

            FakeDatabase fake = new FakeDatabase();

            _source = fake.GenerateFakeSource();

            _totalPage = _source.Count / _pageSize;

            _fakeSoruce = new ObservableCollection<FakeDatabase>();

            List<FakeDatabase> result = _source.Take(20).ToList();

            _fakeSoruce.Clear();

            _fakeSoruce.AddRange(result);

            _firstPageCommand = new DelegateCommand(FirstPageAction);

            _previousPageCommand = new DelegateCommand(PreviousPageAction);

            _nextPageCommand = new DelegateCommand(NextPageAction);

            _lastPageCommand = new DelegateCommand(LastPageAction);
        

        private void FirstPageAction()
        
            CurrentPage = 1;

            var result = _source.Take(_pageSize).ToList();

            _fakeSoruce.Clear();

            _fakeSoruce.AddRange(result);
        

        private void PreviousPageAction()
        
            if(CurrentPage == 1)
            
                return;
            

            List<FakeDatabase> result = new List<FakeDatabase>();

            if(CurrentPage == 2)
            
                result = _source.Take(_pageSize).ToList();
            
            else
            
                result = _source.Skip((CurrentPage - 2) * _pageSize).Take(_pageSize).ToList();
            

            _fakeSoruce.Clear();

            _fakeSoruce.AddRange(result);

            CurrentPage--;
        

        private void NextPageAction()
        
            if(CurrentPage == _totalPage)
            
                return;
            

            List<FakeDatabase> result = new List<FakeDatabase>();

            result = _source.Skip(CurrentPage * _pageSize).Take(_pageSize).ToList();

            _fakeSoruce.Clear();

            _fakeSoruce.AddRange(result);

            CurrentPage++;
        

        private void LastPageAction()
        
            CurrentPage = TotalPage;

            int skipCount = (_totalPage - 1) * _pageSize;
            int takeCount = _source.Count - skipCount;

            var result = _source.Skip(skipCount).Take(takeCount).ToList();

            _fakeSoruce.Clear();

            _fakeSoruce.AddRange(result);
        
    
技术图片

绑定到UI的数据源只是需要显示的数据,不会把所有数据都取出来。当选择显示页数时,只需要将新的数据源附上即可。
技术图片

总结:如果需要对该分页控件进行扩展,例如,增加每页显示条数功能,只需要在Pager控件中增加相应的依赖属性即可。

感谢您的阅读,代码点击这里下载。

wpf实现datagrid/listview分页控件(转)(代码片段)

 在WPF中,通常会选用DataGrid/ListView进行数据展示,如果数据量不多,可以直接一个页面显示出来。如果数据量很大,2000条数据,一次性显示在一个页面中,不仅消耗资源,而且用户体验也很糟糕。这篇博客将介绍如何创建一... 查看详情

WPF 中的分页集合视图

...-12-2116:13:37【问题描述】:在WPF中是否有PagedCollectionView的实现?它存在于Silverlight中,但不在WPF中。如果没有,最简单的实现方法是什么?【问题讨论】:***.com/questions/784726/…的可能重复【参考方案1】:您可以简单地从Silverlight... 查看详情

wpf使用mvvm实现数据分页组件(代码片段)

  前台代码<UserControlx:Class="GasWpf.View.ucPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schem 查看详情

wpf中如何实现分页打印!主要是打印datagrid控件中的数据,若实现打印数据库中查询出的数据也可以。

PrintVisual()方法如果实现不了分页,就不要说了,这个我知道的!急急!参考技术A用报表生成器可以很容易实现的 查看详情

c#wpf将xaml打印成pdf并能实现分页,ps:xaml里面是一个fixedpage的控件,请问该怎么做

xaml只有一张,因为里面有datagrid报表,比较大张,打印的pdf要能分页参考技术A刚开始学,看视频里面没有关于WPF内打印XAML页面的控件 参考技术Bxaml其实转为xps比较方便,xps也可以直接打印!追问如何分页呢 查看详情

使用分页 CollectionView 的 WPF 可编辑 DataGrid

】使用分页CollectionView的WPF可编辑DataGrid【英文标题】:WPFEditableDataGridusingaPagedCollectionView【发布时间】:2014-10-1006:09:18【问题描述】:我正在按照本文PaginationinWPF中的建议实现分页数据网格。一切正常,但我的网格中有一些复选... 查看详情

wpf项目学习.三

...件的制作,邮件发送,日志代码,excel导入导出等代码的实现过程; 二、配置系统环境:win10开发工具:VisualStudio2017开发语言:C#.WPF(MVVM框架) 三、功能  1.分页控件的制作1.1前端xaml代码< 查看详情

在devexpress程序中使用winform分页控件直接录入数据并保存

...要介绍在DevExpress程序中使用GridView直接录入数据并保存的实现,以及使用Winform分页控 查看详情

使用 WPF 和使用存储过程进行分页

】使用WPF和使用存储过程进行分页【英文标题】:PagingusingWPFandusingstoredprocedure【发布时间】:2015-11-1823:09:01【问题描述】:分页控件用于WPF应用程序中。但是分页控件是在WCF应用程序引用存储过程之后在存储过程中创建的。【... 查看详情

wpf管理系统自定义分页控件-wpf特工队内部资料(代码片段)

原文:WPF管理系统自定义分页控件-WPF特工队内部资料  最近做一个演示的管理系统项目,需要用到分页控件,在网上找了很多,依然找到与UI模版匹配的,最后干脆自己写一个。  分页控件分析:    1、分页控件分简单... 查看详情

winformdatagridview大数据量和虚拟模式实例。该怎么处理

...了。MSDN的实例有些没看懂。wpf倒是有数据虚拟化,首先实现滚动条,然后滚动到元素后,再构造视图,离开后,释放视图,继承了虚拟化方法的控件都可以实现;winform只能靠自己去实现了,我觉得你现在的实力不够实现象wpf那... 查看详情

[wpf]wpfdatavirtualization和uivirtualization

...alization原生态的支持,当时我们可以使用Paging相关技术来实现。在我先前的博客WPF实现 查看详情

如何对 WPF DataGrid 进行分页?

】如何对WPFDataGrid进行分页?【英文标题】:HowcanIpaginateaWPFDataGrid?【发布时间】:2010-10-2113:08:30【问题描述】:如何在wpfDataGrid中设置分页?【问题讨论】:请在代码项目中查看post【参考方案1】:上面的代码项目文章非常适合... 查看详情

wpfdatagrid如何分页、导出excle、打印(急)

...现就要走人,哪位好心人帮一下忙,跪谢!注(是WPF里的DataGrid,另外到处可以选中行导出和全部导出)分页是实现前一页,后一页,最前页,最后页,当前页号/总页号;可以获取数据源,可是数据源始对象列表,并且可以获取... 查看详情

wpf分页控件(代码片段)

最近要写个程序要用到分页控件,找到了很多好高级的,代码拿到了也看不懂。最后找到了一个能看懂的,完善了一下。源控件https://www.cnblogs.com/madehua/archive/2011/12/14/2287672.html  页面代码<UserControlx:Class="WpfCustomControlLibra... 查看详情

wpf之列表分页控件(代码片段)

 WPF之列表分页控件控件名:WindowAcrylicBlur作者:WPFDevelopersOrg -黄佳|驚鏵原文链接:  https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40。VisualStudio2022。项目使用MIT开源许可协议。新建Pagination自定义控件... 查看详情

2021-11-07wpf上位机78-智能停车场项目专题-分页控件的封装(代码片段)

PaginationModelpublicclassPaginationModel:BindableBase#region构造函数publicPaginationModel() 查看详情

wpf实现弹幕

实现效果运用WPF的DoubleAnimation实现桌面端的弹幕效果示例代码https://github.com/zLulus/BarrageDemo 查看详情