一、分页控件功能说明

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

  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);
}
}

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

最新文章

  1. [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密
  2. JQuery中Ajax的操作
  3. 通过CSS实现小动物
  4. 使用Path语法取得对象的值
  5. eclipse sdk 无法更新
  6. java web线程池
  7. 如何在Ubuntu下使用TF/SD 卡制作Exynos 4412 u-boot启动盘
  8. Java学习笔记(一) java介绍
  9. 本地缓存下载文件,download的二次封装
  10. C#下的 Emgu CV
  11. HDOJ1175连连看 DFS
  12. .Net 内存池
  13. LeetCode(69)-Reverse String
  14. 使用List和Map遇到得空指针异常
  15. 2079 ACM 选课时间 背包 或 母函数
  16. UEditor百度编辑器,工具栏自定义添加一个普通按钮
  17. 可以进行SHA-1,SHA-224,SHA-256,SHA-384,SHA-512五种算法签名的工具类,以及简单说明
  18. C# Winform 怎么让按钮在Panel里居中显示
  19. 通达信k线颜色设置
  20. OpenCV for Python常用命令

热门文章

  1. CSS-clear属性的作用
  2. python模块的打包和安装
  3. 07-Spring ConfigurationClassPostProcessor
  4. 攻防世界 reverse leaked-license-64
  5. Android控件 之 TextClock &amp; AnalogClock(模拟时钟)
  6. docker部署kafka集群
  7. 高可用负载均衡 haproxy+keepalived
  8. 冒泡算法(BubbleSort)
  9. 滴水逆向初级-C语言(二)
  10. 201871030135-姚辉 实验二 个人项目—《D{0-1} KP》项目报告