广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >自定义WPF分页控件的全过程记录
  • 202
分享到

自定义WPF分页控件的全过程记录

2024-04-02 19:04:59 202人浏览 泡泡鱼
摘要

一、分页控件功能说明# 实现如上图所示的分页控件,需要实现一下几个功能: 可以设置每页能够展示的最大列数(例如每页8列、每页16列等等)。 加载的数组总数量超过

一、分页控件功能说明#

实现如上图所示的分页控件,需要实现一下几个功能:

  1. 可以设置每页能够展示的最大列数(例如每页8列、每页16列等等)。
  2. 加载的数组总数量超过设置的每页列数后,需分页展示。
  3. 可以直接点击指定的列数或者上下页按钮进行页面跳转

二、自定义分页控件使用说明#

为了实现以上功能,主要进行以下工作:

1、添加一个自定义按钮PagerButton类,声明一个依赖属性IsActive,用于记录当前页面所在页数的按钮,此时该按钮边框高亮显示,具体代码如下:


 public class PagerButton : Button
    {
        public bool IsActive
        {
            get { return (bool)GetValue(IsActiveProperty); }
            set { SetValue(IsActiveProperty, value); }
        }

        public static readonly DependencyProperty IsActiveProperty =
            DependencyProperty.ReGISter("IsActive", typeof(bool), typeof(PagerButton), new PropertyMetadata(false));

    }


  <Style x:Key="PagerButtonStyle" TargetType="controls:PagerButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="controls:PagerButton">
                    <Border x:Name="b1" CornerRadius="2" Background="{StaticResource Themes}"
                                            BorderThickness="1" BorderBrush="{StaticResource Disabled}"
                                            Width="32" Height="32" Margin="4,0">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="b1" Property="BorderBrush" Value="{StaticResource Accent}"></Setter>
                        </Trigger>
                        <Trigger Property="IsActive" Value="True">
                            <Setter TargetName="b1" Property="BorderBrush" Value="{StaticResource Accent}"></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
        </Style.Triggers>
    </Style>

2、添加自定义分页控件PagerBar类,用于展示分页按钮(使用PagerButton类)和实现分页跳转,需要定义当前页面、总页数、设置的每页最大列数三个依赖属性,具体如下:


   public int CurrentPageIndex
        {
            get { return (int)GetValue(CurrentPageIndexProperty); }
            set { SetValue(CurrentPageIndexProperty, value); }
        }
        public int PageSize
        {
            get { return (int)GetValue(PageSizeProperty); }
            set { SetValue(PageSizeProperty, value); }
        }
        public int PageCount
        {
            get { return (int)GetValue(PageCountProperty); }
            set { SetValue(PageCountProperty, value); }
        }

        public static readonly DependencyProperty CurrentPageIndexProperty = DependencyProperty.Register("CurrentPageIndex", typeof(int), typeof(PagerBar), new PropertyMetadata(-1, CurrentPageIndexPropertyChangedCallback));
        public static readonly DependencyProperty PageSizeProperty = DependencyProperty.Register("PageSize", typeof(int), typeof(PagerBar), new PropertyMetadata(10, PageSizePropertyChangedCallback));
        public static readonly DependencyProperty PageCountProperty = DependencyProperty.Register("PageCount", typeof(int), typeof(PagerBar), new PropertyMetadata(-1, PageCountPropertyChangedCallback));

3、添加一个工具类Pager,用于将数据按照要求分页,该工具类声明当前页数、总页数、设置的每页最大列数三个属性,具体如下:


  public int PageSize
        {
            get => _pageSize;
            set
            {
                if (value == _pageSize)
                    return;
                _pageSize = value;
                OnPropertyChanged();
                SetPageSize(_pageSize);
            }
        }
        public int PageCount
        {
            get => _pageCount;
            set
            {
                if (value == _pageCount)
                    return;
                _pageCount = value;

                // 最少页为1页
                if (_pageCount == 0)
                    _pageCount = 1;
                OnPropertyChanged();
            }
        }
        public int CurPageIndex
        {
            get => _curPageIndex;
            set
            {
                if (value == _curPageIndex)
                    return;
                _curPageIndex = value;
                OnPropertyChanged();
                GotoPageOf(_curPageIndex);
            }
        }

4、将Pager类和PageBar控件进行数据绑定。具体操作为:在绑定的ViewModel上声明一个Pager类,然后将该Pager类的属性和PagrBar进行一一对应绑定。具体代码如下:


  <controls:PagerBar Grid.Row="1" Margin="5"
                           HorizontalAlignment="Center"
                           PageSize="{Binding Path=Pager.PageSize, Mode=TwoWay}" 
                           PageCount="{Binding Path=Pager.PageCount, Mode=TwoWay}"  
                           CurrentPageIndex="{Binding Path=Pager.CurPageIndex, Mode=TwoWay}"></controls:PagerBar>

5、初始化Pager类时,在界面绑定的ViewModel里面重新声明一个数组,用于保存分页后的数组,将该数组绑定到待展示的条目控件(例如ListBox)上,具体如下:


 StudentCollection=new ObservableCollection<Student>();
            for (int i = 0; i < 10; i++)
            {
                StudentCollection.Add(new Student()
                {
                    Id = Index = i,
                    Source = 10 * (i + 1),
                });
            }

            AddCommand =new RelayCommand(ExecuteAddCommand);
            DeleteCommand=new RelayCommand(ExecuteDeleteCommand);
            SortCommand=new RelayCommand(ExecuteSortCommand);

            Pager=new Pager<Student>(8,StudentCollection);
            Pager.PagerUpdated += items =>
            {
                StudentCollectionPaging = new ObservableCollection<Student>(items);
            };
            Pager.CurPageIndex = 1;
  <ListBox x:Name="ListBoxStudent" Grid.Row="0"
                 ItemsSource="{Binding StudentCollectionPaging}"
                 ItemTemplate="{StaticResource StudentDateTemplate}"></ListBox>

三、总结说明#

​ 为了实现绑定的数组添加、删除时,PageBar分组控件也能立即更新控件,Pager工具类增加以下构造函数,首先保证数组为同一引用,其次使用ObservableCollection保证界面和ViewModel即时更新:


    public Pager(int pageSize, ObservableCollection<T> source)
        {
            _pageSize = pageSize;
            _itemsSource = source;
            _itemsSource.CollectionChanged += ItemsSourceOnCollectionChanged;
            CalculatePaging();
        }

        private void ItemsSourceOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            CalculatePaging();
            GotoPageOf(CurPageIndex);
        }

四、示例源码#

示例源码地址:分页控件源码

五、问题#

​ 在实际应用中,发现如下问题:当需要对绑定的整个数组进行排序时,由于Pager类初始化传入的数组必须和实际数为同一个引用且必须为ObservableCollection数组,那么使用LINQ排序完成后,必须要使用ToList进行转换,就必须重新初始化ObservableCollection,那么后续当该ObservableCollection数组变化时,也无法通知到Pager类的数组了。为了解决该问题,想到以下两个方法:

(1)自定义排序,针对ObservableCollection的每个数组对象进行排序。这样排序完成后ObservableCollection引用无变化。

(2)先用临时变量保存排序完成的数组,然后清空ObservableCollection,然后再迭代添加临时数组。如此,ObservableCollection对象前后也为统一引用。


  public ICommand SortCommand { get; set; }

        private void ExecuteSortCommand(object obj)
        {
            var list = StudentCollection.ToList().OrderByDescending(item=>item.Source).ToList();
            StudentCollection.Clear();
            foreach (var item in list)
            {
                StudentCollection.Add(item);
            }
        }

目前暂时采用了第二种方法,但该方法效率不高。后续有更好的解决方法可以留言讨论。

总结

到此这篇关于自定义WPF分页控件的文章就介绍到这了,更多相关自定义WPF分页控件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 自定义WPF分页控件的全过程记录

本文链接: https://www.lsjlt.com/news/126377.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 自定义WPF分页控件的全过程记录
    一、分页控件功能说明# 实现如上图所示的分页控件,需要实现一下几个功能: 可以设置每页能够展示的最大列数(例如每页8列、每页16列等等)。 加载的数组总数量超过...
    99+
    2022-11-12
  • Flutter构建自定义Widgets的全过程记录
    目录一.组合widget实现二.通过自定义CustomPainter实现widgets三.饼状图piechart.dart代码展示四.实际效果图,eg:附:Flutter中父widg...
    99+
    2022-11-12
  • MyBatis-Plus自定义SQL的详细过程记录
    目录前言一、在src/main/resource目录下编写XML1.1  目录结构1.2   编写实体类对应的Mapper接口1.3 ...
    99+
    2022-11-13
  • vue自定义表格列的实现过程记录
    目录前言效果图 setTable组件 使用 结束语 前言 在我们开发PC端的项目使用表单时,尤其是crm系统,应该经常会遇到这样的需求, 用户需要根据设置来自定义显示列。 查了ele...
    99+
    2022-11-12
  • GridView中如何自定义分页的存储过程
    GridView中如何自定义分页的存储过程,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. 为什么不使用GridView的默...
    99+
    2022-10-18
  • Zabbix自定义脚本监控nginx以及微信告警的全过程
    目录项目描述项目步骤项目心得详细步骤zabbix-agent客户端nginx配置监控zabbix-server-web配置监控注册企业微信接口zabbix-server接口脚本配置告...
    99+
    2022-11-13
  • vue3+vite自定义封装vue组件发布到npm包的全过程
    目录创建项目创建组件导出组件使用vite构建打包注册->登录npm发布前准备发布到npm参考:总结创建项目 “vue”: “^3.2.8&r...
    99+
    2022-11-13
  • Feign远程调用传递对象参数并返回自定义分页数据的过程解析
    目录Feign介绍Feign测试1.在yml文件里面增加了配置信息2.在客户端pom.xml文件中引入的依赖(消费者端)3.服务调用端接口为4.服务调用端Service代码5.服务调...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作