using BPA.UIControl.Commons; using BPA.UIControl.Commons.KnownBoxes; using BPA.UIControl.Models; using Microsoft.VisualBasic; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace BPA.UIControl { /// /// 页码条 /// [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(PageBarItem))] public class PageBar : ItemsControl { static PageBar() { DefaultStyleKeyProperty.OverrideMetadata(typeof(PageBar), new FrameworkPropertyMetadata(typeof(PageBar))); } /// protected override bool IsItemItsOwnContainerOverride(object item) { return item is PageBarItem; } /// protected override DependencyObject GetContainerForItemOverride() { return new PageBarItem(); } #region 命令 /// /// 每页数量改变命令 /// public ICommand PageSizeChangedCommand { get { return (ICommand)GetValue(PageSizeChangedCommandProperty); } set { SetValue(PageSizeChangedCommandProperty, value); } } public static readonly DependencyProperty PageSizeChangedCommandProperty = DependencyProperty.Register("PageSizeChangedCommand", typeof(ICommand), typeof(PageBar), new(default(ICommand))); /// /// 当前页改变命令 /// public ICommand PageIndexChangedCommand { get { return (ICommand)GetValue(PageIndexChangedCommandProperty); } set { SetValue(PageIndexChangedCommandProperty, value); } } public static readonly DependencyProperty PageIndexChangedCommandProperty = DependencyProperty.Register("PageIndexChangedCommand", typeof(ICommand), typeof(PageBar), new(default(ICommand))); #endregion 命令 #region 事件 /// /// 每页数量改变事件 /// public static readonly RoutedEvent PageSizeChangedEvent = EventManager.RegisterRoutedEvent("PageSizeChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(PageBar)); /// /// 每页数量改变事件 /// public event RoutedPropertyChangedEventHandler PageSizeChanged { add { AddHandler(PageSizeChangedEvent, value); } remove { RemoveHandler(PageSizeChangedEvent, value); } } /// /// 当前页改变事件 /// public static readonly RoutedEvent PageIndexChangedEvent = EventManager.RegisterRoutedEvent("PageIndexChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(PageBar)); /// /// 当前页改变事件 /// public event RoutedPropertyChangedEventHandler PageIndexChanged { add { AddHandler(PageIndexChangedEvent, value); } remove { RemoveHandler(PageIndexChangedEvent, value); } } #endregion 事件 #region 依赖属性 /// /// 未选中颜色 /// public Brush UnselectedBrush { get { return (Brush)GetValue(UnselectedBrushProperty); } set { SetValue(UnselectedBrushProperty, value); } } public static readonly DependencyProperty UnselectedBrushProperty = DependencyProperty.Register("UnselectedBrush", typeof(Brush), typeof(PageBar), new(default(Brush))); /// /// 选中颜色 /// public Brush SelectedBrush { get { return (Brush)GetValue(SelectedBrushProperty); } set { SetValue(SelectedBrushProperty, value); } } public static readonly DependencyProperty SelectedBrushProperty = DependencyProperty.Register("SelectedBrush", typeof(Brush), typeof(PageBar), new(default(Brush))); /// /// 当前前景色 /// public Brush SelectedForeground { get { return (Brush)GetValue(SelectedForegroundProperty); } set { SetValue(SelectedForegroundProperty, value); } } public static readonly DependencyProperty SelectedForegroundProperty = DependencyProperty.Register("SelectedForeground", typeof(Brush), typeof(PageBar), new(default(Brush))); /// /// 每页数量 /// public int PageSize { get { return (int)GetValue(PageSizeProperty); } set { SetValue(PageSizeProperty, value); } } public static readonly DependencyProperty PageSizeProperty = DependencyProperty.Register("PageSize", typeof(int), typeof(PageBar), new(0, new((d, e) => { PageBar pageBar = (PageBar)d; CheckPageSize(pageBar); pageBar.PageIndex = 1; pageBar.ReFreshPageBar(); int oldValue = (int)e.OldValue; int newValue = (int)e.NewValue; RoutedPropertyChangedEventArgs args = new RoutedPropertyChangedEventArgs(oldValue, newValue); CollectionRefresh(pageBar); args.RoutedEvent = PageBar.PageSizeChangedEvent; pageBar.RaiseEvent(args); pageBar.PageSizeChangedCommand?.Execute(newValue); }))); private static void CheckPageSize(PageBar pageBar) { if (!pageBar.PageSizeCollection.Contains(pageBar.PageSize)) { pageBar.PageSize = pageBar.PageSizeCollection.FirstOrDefault(); } } /// /// 每页数量集合 /// [TypeConverter(typeof(PageSizeCollectionConverter))] public IEnumerable PageSizeCollection { get { return (IEnumerable)GetValue(PageSizeCollectionProperty); } set { SetValue(PageSizeCollectionProperty, value); } } public static readonly DependencyProperty PageSizeCollectionProperty = DependencyProperty.Register("PageSizeCollection", typeof(IEnumerable), typeof(PageBar), new FrameworkPropertyMetadata(Enumerable.Range(1, 4).Select(x => x * 5), FrameworkPropertyMetadataOptions.AffectsParentMeasure, (d, e) => { CheckPageSize(d as PageBar); })); /// /// 当前页 /// public int PageIndex { get { return (int)GetValue(PageIndexProperty); } set { SetValue(PageIndexProperty, value); } } public static readonly DependencyProperty PageIndexProperty = DependencyProperty.Register("PageIndex", typeof(int), typeof(PageBar), new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new((d, e) => { PageBar pageBar = (PageBar)d; pageBar.ReFreshPageBar(); int oldValue = (int)e.OldValue; int newValue = (int)e.NewValue; RoutedPropertyChangedEventArgs args = new RoutedPropertyChangedEventArgs(oldValue, newValue); CollectionRefresh(pageBar); args.RoutedEvent = PageBar.PageIndexChangedEvent; pageBar.RaiseEvent(args); pageBar.PageIndexChangedCommand?.Execute(newValue); }))); /// /// 总数量 /// public int Total { get { return (int)GetValue(TotalProperty); } set { SetValue(TotalProperty, value); } } public static readonly DependencyProperty TotalProperty = DependencyProperty.Register("Total", typeof(int), typeof(PageBar), new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new((d, e) => { PageBar pageBar = (PageBar)d; pageBar.ReFreshPageBar(); CollectionRefresh(pageBar); }))); /// /// 是否显示总数量 /// public bool IsShowTotal { get { return (bool)GetValue(IsShowTotalProperty); } set { SetValue(IsShowTotalProperty, value); } } public static readonly DependencyProperty IsShowTotalProperty = DependencyProperty.Register("IsShowTotal", typeof(bool), typeof(PageBar), new(BooleanBoxes.FalseBox)); /// /// 是否显示每页数量 /// public bool IsShowPageSize { get { return (bool)GetValue(IsShowPageSizeProperty); } set { SetValue(IsShowPageSizeProperty, value); } } public static readonly DependencyProperty IsShowPageSizeProperty = DependencyProperty.Register("IsShowPageSize", typeof(bool), typeof(PageBar), new(BooleanBoxes.FalseBox)); /// /// 子项停靠方向 /// public Dock ItemsDock { get { return (Dock)GetValue(ItemsDockProperty); } set { SetValue(ItemsDockProperty, value); } } public static readonly DependencyProperty ItemsDockProperty = DependencyProperty.Register("ItemsDock", typeof(Dock), typeof(PageBar), new(Dock.Right)); /// /// 子项内边距 /// public Thickness ItemsPadding { get { return (Thickness)GetValue(ItemsPaddingProperty); } set { SetValue(ItemsPaddingProperty, value); } } public static readonly DependencyProperty ItemsPaddingProperty = DependencyProperty.Register("ItemsPadding", typeof(Thickness), typeof(PageBar), new(default(Thickness))); /// /// 是否圆角 /// public bool IsRound { get { return (bool)GetValue(IsRoundProperty); } set { SetValue(IsRoundProperty, value); } } public static readonly DependencyProperty IsRoundProperty = DependencyProperty.Register("IsRound", typeof(bool), typeof(PageBar), new(BooleanBoxes.FalseBox)); /// /// 需要分页的数据源 /// public IEnumerable DataSource { get { return (IEnumerable)GetValue(DataSourceProperty); } set { SetValue(DataSourceProperty, value); } } public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(IEnumerable), typeof(PageBar), new PropertyMetadata(default, new PropertyChangedCallback((d, e) => { PageBar pageBar = (PageBar)d; var res = pageBar.DataSource as ICollection; if (res != null) { pageBar.Total = res.Count; } }))); /// /// 分页后的数据源 /// public IEnumerable CurrentDataSource { get { return (IEnumerable)GetValue(CurrentDataSourceProperty); } set { SetValue(CurrentDataSourceProperty, value); } } public static readonly DependencyProperty CurrentDataSourceProperty = DependencyProperty.Register("CurrentDataSource", typeof(IEnumerable), typeof(PageBar), new PropertyMetadata(new ObservableCollection())); #endregion 依赖属性 #region 方法 private static void CollectionRefresh(PageBar pageBar) { if (pageBar == null) return; int temp = pageBar.PageIndex * pageBar.PageSize; var ds = new ObservableCollection(); var cds = new ObservableCollection(); pageBar.DataSource?.Cast()?.ToList()?.ForEach(item => { ds.Add(item); }); if (ds != null && cds != null) { cds.Clear(); for (int i = temp - pageBar.PageSize; i < temp; i++) { if (i >= 0 && i < ds.Count) cds.Add(ds[i]); } pageBar.CurrentDataSource = cds; } } //private void CollectionRefresh() //{ // int temp = PageIndex * PageSize; // var ds = new ObservableCollection(); // var cds = new ObservableCollection(); // DataSource?.Cast()?.ToList()?.ForEach(item => { ds.Add(item); }); // if (ds != null && cds != null) // { // cds.Clear(); // for (int i = temp - PageSize; i < temp; i++) // { // if (i >= 0 && i < ds.Count) cds.Add(ds[i]); // } // CurrentDataSource = cds; // } //} // 刷新页码条 private void ReFreshPageBar() { List models = new List(); if (PageSize == 0 || Total == 0) { this.ItemsSource = models; return; } int pageCount = (int)Math.Ceiling(Total / (PageSize * 1.0)); // 总共多少页 models.Add(new PageItemModel { Content = "<", ToolTip = Application.Current.Resources["I18N_PageBar_PreviousPage"].ToString(), Value = PageIndex - 1, IsEnabled = PageIndex != 1 && pageCount != 1, Command = new BPACommand(PageNumberChanged) }); models.Add(new PageItemModel { Content = 1, Value = 1, IsEnabled = true, Command = new BPACommand(PageNumberChanged) }); int begin; int end; begin = PageIndex >= 6 ? PageIndex - 3 : 2; // index 大于等于 6 页就从 index-3 开始,否则 2 开始 end = PageIndex + 3 >= pageCount ? pageCount - 1 : PageIndex + 3; // index+3 大于 total 就 total-1 结束,否则 index + 3 // 补够按键数量 if (end - begin < 6) { if (PageIndex - begin < 3) { end += 3 - (PageIndex - begin); end = end > pageCount - 1 ? pageCount - 1 : end; } else if (end - PageIndex < 3) { begin -= 3 - (end - PageIndex); begin = begin < 2 ? 2 : begin; } } for (int i = begin; i <= end; i++) { var model = new PageItemModel { Value = i, Content = i, IsEnabled = true, Command = new BPACommand(PageNumberChanged) }; if (pageCount > 9) { if (i == begin && PageIndex - begin >= 3 && PageIndex > 5) { model.Value = PageIndex - 5; model.Content = "..."; model.ToolTip = Application.Current.Resources["I18N_PageBar_Forward5Pages"].ToString(); } else if (i == end && end - PageIndex >= 3 && pageCount - PageIndex >= 5) { model.Value = PageIndex + 5; model.Content = "..."; model.ToolTip = Application.Current.Resources["I18N_PageBar_Backwards5Pages"].ToString(); } } models.Add(model); } // 最后一页 if (pageCount > 1) { models.Add(new PageItemModel { Content = pageCount, Value = pageCount, IsEnabled = true, Command = new BPACommand(PageNumberChanged) }); } // 下一页 models.Add(new PageItemModel { Content = ">", ToolTip = Application.Current.Resources["I18N_PageBar_NextPage"].ToString(), Value = PageIndex + 1, IsEnabled = PageIndex != pageCount && pageCount != 1, Command = new BPACommand(PageNumberChanged) }); this.ItemsSource = models; } private void PageNumberChanged(object index) { PageIndex = (int)index; } #endregion 方法 } }