WPF随笔(七)--分页控件

不管是桌面应用还是Web应用,表单、列表都是大部分应用常见的展现形式,而一个方便易用的分页控件能够很大程度上改善列表的交互体验。本篇就来说明如何用户控件实现一个简单的WPF分页控件。


页面结构

从展示层面来讲,一个分页控件一般会包括首页、尾页、上一页、下一页以及当前页码等内容,在精细一些可以加上跳转到特定页码、设置每页显示行数等功能。
本次的简单分页控件就暂时只包含首页、尾页、上页、下页的功能,页面结构如下。

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <WrapPanel Grid.Column="0" VerticalAlignment="Center">
            <TextBlock>当前显示第</TextBlock>
            <TextBlock Name="txtIndex"/>
            <TextBlock>页,每页</TextBlock>
            <TextBlock Name="txtNumber">10</TextBlock>
            <TextBlock>条/共</TextBlock>
            <TextBlock Name="txtTotal">0</TextBlock>
            <TextBlock></TextBlock>
        </WrapPanel>
        <WrapPanel Grid.Column="1" VerticalAlignment="Center">
            <Button Name="btnFirst" Click="btnFirst_Click">首页</Button>
            <Button Name="btnPrev" Click="btnPrev_Click">上一页</Button >
            <Grid Name="grid">
                <StackPanel Orientation="Horizontal" x:Name="sp">
                    <TextBlock>1</TextBlock>
                    <TextBlock>2</TextBlock>
                    <TextBlock>3</TextBlock>
                </StackPanel>
            </Grid>
            <Button Name="btnNext" Click="btnNext_Click">下一页</Button >
            <Button Name="btnLast" Click="btnLast_Click">尾页</Button >
        </WrapPanel>
    </Grid>

代码实现

构建界面仅仅是第一步,界面与有效的代码结合起来才能实现必要的效果。代码的实现上主要包括两部分,第一部分是对数据源的操作,第二部分是首页、尾页等按钮的操作效果。

相关变量

        private DataTable _dt = new DataTable();//数据源
        private int _pageNum; //每页显示条数
        private int _pageIndex = 1;//当前页码
        public int PageIndex
        {
			get{return _pageIndex;}
			set{_pageIndex=value;}
		}
        private int _maxIndex = 1; //总页数
        private int _totalNum; //总条数
        private DataGrid _dg;//列表控件

数据操作

        #region 初始化数据

        public void ShowPages(DataGrid datagrid, DataTable datatable, int num)
        {
            if (datatable != null) //&&datatable.Rows.Count>0
            {
                _dt = datatable.Clone();
                _dg = datagrid;
                _pageNum = num;
                _pageIndex = 1;
                _totalNum = datatable.Rows.Count;
                if (datatable.Rows.Count % num == 0)
                {
                    _maxIndex = datatable.Rows.Count / num;
                }
                else
                {
                    _maxIndex = datatable.Rows.Count / num + 1;
                }
                foreach (DataRow dr in datatable.Rows)
                {
                    _dt.ImportRow(dr);
                }
            }
            ReadDataTable();
        }

        #endregion

        #region 读取数据

        private void ReadDataTable()
        {
            try
            {
                DataTable tmpTable = _dt.Clone();
                int first = _pageNum * (_pageIndex - 1);
                first = first > 0 ? first : 0;
                if (_dt.Rows.Count >= _pageNum * _pageIndex )
                {
                    for (int i = first; i < _pageNum * _pageIndex ; i++)
                    {
                        tmpTable.ImportRow(_dt.Rows[i]);
                    }
                }
                else
                {
                    for (int i = first; i < _dt.Rows.Count; i++)
                    {
                        tmpTable.ImportRow(_dt.Rows[i]);
                    }
                }
                _dg.ItemsSource = tmpTable.DefaultView;
                tmpTable.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                DisplayPagingInfo();
            }
        }

        #endregion

        #region 显示数据

        private void DisplayPagingInfo()
        {
            if (_pageIndex == 1)
            {
                btnFirst.IsEnabled = false;
                btnPrev.IsEnabled = false;
            }
            else
            {
                btnFirst.IsEnabled = true;
                btnPrev.IsEnabled = true;
            }
            if (_pageIndex == _maxIndex)
            {
                btnNext.IsEnabled = false;
                btnLast.IsEnabled = false;
            }
            else
            {
                btnLast.IsEnabled = true;
                btnNext.IsEnabled = true;
            }
            txtNumber.Text = _pageNum.ToString();
            txtTotal.Text = _totalNum.ToString();
            txtIndex.Text = _pageIndex .ToString();

            int num = 9;
            if (_maxIndex < num) num = _maxIndex - 1;//如果总页数不够10
            int currint = num / 2;
            int first = (_pageIndex > currint ? _pageIndex - currint : 1);//起始
            int last = (_pageIndex + currint > _maxIndex ? _maxIndex : _pageIndex + currint);//结束

            //为避免currentpage小于5时,以及避免最后几页显示不到10项,加上下面两行
            if (last <= num) last = num + 1;
            if (last - first < num) first = last - num;
            if (_pageIndex > _maxIndex) _pageIndex = _maxIndex;
            sp.Children.Clear();
            for (int i = first; i <= last; i++)
            {
                TextBlock tb = new TextBlock();
                tb.Text = i.ToString();
                tb.TextAlignment = TextAlignment.Center;
                tb.MouseLeftButtonDown += tb_MouseLeftButtonDown;
                tb.MouseLeftButtonUp += tb_MouseLeftButtonUp;
                if (i == _pageIndex )
                {
                    tb.IsEnabled = false;
                }
                sp.Children.Add(tb);
            }
        }

        private void tb_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            if (tb == null)
            {
                return;
            }
            int index = int.Parse(tb.Text);
            _pageIndex = index;
            if (index > _maxIndex)
            {
                _pageIndex = _maxIndex;
            }
            if (index < 1)
            {
                _pageIndex = 1;
            }
            ReadDataTable();
        }

        private void tb_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        #endregion

操作按钮

        #region 首页
        private void btnFirst_Click(object sender, EventArgs e)
        {
            _pageIndex= 1;
            ReadDataTable();
        }

        #endregion

        #region 上一页
        private void btnPrev_Click(object sender, EventArgs e)
        {
            if (_pageIndex<= 1)
            {
                return;
            }
            _pageIndex--;
            ReadDataTable();
        }

        #endregion

        #region 下一页
        private void btnNext_Click(object sender, EventArgs e)
        {
            if (_pageIndex>= _maxIndex)
            {
                return;
            }
            _pageIndex++;
            ReadDataTable();
        }

        #endregion

        #region 末页

        private void btnLast_Click(object sender, EventArgs e)
        {
            _pageIndex= _maxIndex;
            ReadDataTable();
        }

        #endregion

使用示例

UI界面
<UserControl x:Class="WPFDemo.DataPageDemo"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:WPFDemo"
             mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <DataGrid x:Name="dataGrid"  SelectionMode="Extended" SelectionUnit="FullRow" Grid.Row="0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding ID}" Width="*" />
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="*" />
            </DataGrid.Columns>
        </DataGrid>
        <local:DataPager x:Name="dataPager" Grid.Row="1"/>
    </Grid>
</UserControl>
后台代码
private void BindData()
{
	int pageCount=10;
	DataTable dt=new DataTable();
	//此处为获取数据的代码
	dataPager.ShowPages(dataGrid, dt, pageCount);
}

WPF(Windows Presentation Foundation)是一种Microsoft开发的用户界面框架,可以用于创建富客户端的应用程序。MVVM(Model-View-ViewModel)是一种软件架构模式,用于将用户界面的逻辑与数据分离,使开发更易于测试和维护。 在WPF应用程序中实现分页功能,可以通过MVVM来实现。首先,需要创建一个Model类,该类用于存储数据集合的信息。然后,创建一个ViewModel类,该类继承自INotifyPropertyChanged接口,以便在数据发生变化时通知视图进行更新。ViewModel类包含分页的逻辑,例如计算总页数、处理页码变化等。最后,创建一个View类,该类用于显示数据和与用户的交互。 在ViewModel中,可以使用PagingCollectionView类来实现分页。PagingCollectionView类是WPF提供的一个集合视图类,可以将一个集合分成多个页面并进行管理。通过设置PageSize属性,可以指定每个页面显示的数据量;通过设置PageIndex属性,可以指定当前显示的页面索引;通过设置ItemCount属性,可以指定总的数据项数目。在ViewModel中,可以使用命令绑定来处理用户点击页面的操作,然后更新PageIndex属性并重新加载数据。 在View中,可以使用ItemsControl来显示数据,通过绑定ItemsSource属性将ViewModel中的数据源集合与ItemsControl关联起来。通过绑定Command属性将ViewModel中的命令与按钮的点击事件关联起来,从而实现分页操作。 总的来说,使用WPF和MVVM结合的方式来实现分页功能可以使得应用程序的代码结构更清晰、易于维护。ViewModel负责处理页面逻辑,View负责显示数据和用户交互,通过数据绑定和命令绑定来实现数据的更新和操作的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值