分页控件(Pagination)自定义样式

发布时间 2023-07-18 10:35:37作者: DIO·SAMA

以下是分页控件自定义样式资源部分代码

xmlns:controls="clr-namespace:Wallpaper.CustomControls"是Pagination.cs的地址
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:Wallpaper.CustomControls">

    <Style x:Key="WD.PageListBoxStyleKey" TargetType="{x:Type ListBox}">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        SnapsToDevicePixels="True">
                        <ScrollViewer Padding="{TemplateBinding Padding}" Focusable="False">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsGrouping" Value="True">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="False" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="WD.PageListBoxItemStyleKey" TargetType="{x:Type ListBoxItem}">
        <Setter Property="MinWidth" Value="32" />
        <Setter Property="Height" Value="30" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Padding" Value="5,0" />
        <Setter Property="Margin" Value="3,0" />
        <Setter Property="Background" Value="#fedce1" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border
                        Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        CornerRadius="12"
                        SnapsToDevicePixels="True">
                        <ContentPresenter
                            x:Name="PART_ContentPresenter"
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            RecognizesAccessKey="True"
                            TextElement.Foreground="{TemplateBinding Foreground}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding .}" Value="···">
                <Setter Property="IsEnabled" Value="False" />
                <Setter Property="FontWeight" Value="Bold" />
            </DataTrigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="BorderBrush" Value="{DynamicResource WD.DefaultBorderBrushSolidColorBrush}" />
                <Setter Property="Background" Value="{DynamicResource WD.DefaultBackgroundSolidColorBrush}" />
                <Setter Property="Foreground" Value="{DynamicResource WD.PrimaryNormalSolidColorBrush}" />
            </Trigger>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="#fa77b1" />
                <Setter Property="TextElement.Foreground" Value="White" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <ControlTemplate x:Key="WD.LitePagerControlTemplate" TargetType="{x:Type controls:Pagination}">
        <Border
            Padding="{TemplateBinding Padding}"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="10" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="10" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock VerticalAlignment="Center" Text="{Binding Count, StringFormat=共 {0} 条, RelativeSource={RelativeSource TemplatedParent}}" />
                <TextBox
                    x:Name="PART_CountPerPageTextBox"
                    Grid.Column="2"
                    Width="60"
                    MinWidth="0"
                    VerticalContentAlignment="Center"
                    TextAlignment="Center" />
                <TextBlock
                    Grid.Column="3"
                    VerticalAlignment="Center"
                    Text=" 条 / 页" />
                <Button Grid.Column="5" Command="{x:Static controls:Pagination.PrevCommand}">
                    <Path
                        Width="7"
                        Height="10"
                        Data="{StaticResource WD.PreviousGeometry}"
                        Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
                        Stretch="Fill" />
                </Button>
                <TextBox
                    x:Name="PART_JumpPageTextBox"
                    Grid.Column="7"
                    Width="60"
                    MinWidth="0"
                    VerticalContentAlignment="Center"
                    TextAlignment="Center">
                    <TextBox.ToolTip>
                        <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding StringFormat="{}{0}/{1}">
                                    <Binding Path="Current" RelativeSource="{RelativeSource TemplatedParent}" />
                                    <Binding Path="PageCount" RelativeSource="{RelativeSource TemplatedParent}" />
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </TextBox.ToolTip>
                </TextBox>
                <Button Grid.Column="9" Command="{x:Static controls:Pagination.NextCommand}">
                    <Path
                        Width="7"
                        Height="10"
                        Data="{StaticResource WD.NextGeometry}"
                        Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
                        Stretch="Fill" />
                </Button>
            </Grid>
        </Border>
    </ControlTemplate>
    <Style x:Key="WD.Pagination" TargetType="{x:Type controls:Pagination}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:Pagination}">
                    <Border
                        Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <TextBlock
                                Margin="0,0,15,0"
                                VerticalAlignment="Center"
                                Text="{Binding Count, StringFormat=共 {0} 条, RelativeSource={RelativeSource TemplatedParent}}"
                                Visibility="Collapsed" />
                            <StackPanel
                                Grid.Column="1"
                                Margin="0,0,15,0"
                                Orientation="Horizontal"
                                Visibility="Collapsed">
                                <TextBlock VerticalAlignment="Center" Text="每页 " />
                                <TextBox
                                    x:Name="PART_CountPerPageTextBox"
                                    Width="60"
                                    MinWidth="0"
                                    VerticalContentAlignment="Center"
                                    FontSize="{TemplateBinding FontSize}"
                                    TextAlignment="Center" />
                                <TextBlock VerticalAlignment="Center" Text=" 条" />
                            </StackPanel>
                            <Button
                                Grid.Column="2"
                                Padding="0"
                                Background="Transparent"
                                BorderBrush="Transparent"
                                Command="{x:Static controls:Pagination.PrevCommand}">
                                <!--<Path
                                    Width="7"
                                    Height="10"
                                    Data="{TemplateBinding LeftIcon}"
                                    Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
                                    Stretch="Fill" />-->
                                <Image
                                    Width="30"
                                    Height="25"
                                    Source="{TemplateBinding LeftIcon}"
                                    Stretch="Uniform" />
                            </Button>
                            <ListBox
                                x:Name="PART_ListBox"
                                Grid.Column="3"
                                Margin="5,0"
                                ItemContainerStyle="{StaticResource WD.PageListBoxItemStyleKey}"
                                ItemsSource="{TemplateBinding Pages}"
                                ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                                ScrollViewer.VerticalScrollBarVisibility="Hidden"
                                SelectedIndex="0"
                                Style="{StaticResource WD.PageListBoxStyleKey}">
                                <ListBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <UniformGrid Rows="1" />
                                    </ItemsPanelTemplate>
                                </ListBox.ItemsPanel>
                            </ListBox>
                            <Button
                                Grid.Column="4"
                                Padding="0"
                                Background="Transparent"
                                BorderBrush="Transparent"
                                Command="{x:Static controls:Pagination.NextCommand}">
                                <!--<Path
                                    Width="7"
                                    Height="10"
                                    Data="{TemplateBinding RightIcon}"
                                    Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
                                    Stretch="Fill" />-->
                                <Image
                                    Width="30"
                                    Height="25"
                                    Source="{TemplateBinding RightIcon}"
                                    Stretch="Uniform" />
                            </Button>
                            <StackPanel
                                Grid.Column="5"
                                Margin="10,0,0,0"
                                Orientation="Horizontal">
                                <TextBlock VerticalAlignment="Center" Text=" 前往 " />
                                <Border
                                    BorderBrush="#feb9c9" VerticalAlignment="Center" HorizontalAlignment="Center"
                                    BorderThickness="1" Width="40" Height="35" Padding="0" 
                                    CornerRadius="7">
                                    <TextBox
                                        x:Name="PART_JumpPageTextBox"
                                        Width="60"
                                        MinWidth="0" 
                                        VerticalContentAlignment="Center"
                                        HorizontalAlignment="Center"
                                        Background="Transparent"
                                        BorderBrush="Transparent"
                                        ContextMenu="{x:Null}"
                                        FontSize="{TemplateBinding FontSize}"
                                        TextAlignment="Center" />

                                </Border>
                                <TextBlock VerticalAlignment="Center" Text=" 页" />
                            </StackPanel>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsLite" Value="True">
                <Setter Property="Template" Value="{StaticResource WD.LitePagerControlTemplate}" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style
        x:Key="NPPagination"
        BasedOn="{StaticResource WD.Pagination}"
        TargetType="{x:Type controls:Pagination}" />
</ResourceDictionary>

后台绑定代码

[TemplatePart(Name = CountPerPageTextBoxTemplateName, Type = typeof(TextBox))]
    [TemplatePart(Name = JustPageTextBoxTemplateName, Type = typeof(TextBox))]
    [TemplatePart(Name = ListBoxTemplateName, Type = typeof(ListBox))]
    public class Pagination : Control
    {
        private const string CountPerPageTextBoxTemplateName = "PART_CountPerPageTextBox";
        private const string JustPageTextBoxTemplateName = "PART_JumpPageTextBox";
        private const string ListBoxTemplateName = "PART_ListBox";

        private const string Ellipsis = "···";
        private static readonly Type _typeofSelf = typeof(Pagination);

        private TextBox _countPerPageTextBox;
        private TextBox _jumpPageTextBox;
        private ListBox _listBox;

        
        static Pagination()
        {
            InitializeCommands();

            DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf));
        }

        #region Override

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            UnsubscribeEvents();

            _countPerPageTextBox = GetTemplateChild(CountPerPageTextBoxTemplateName) as TextBox;
            if (_countPerPageTextBox != null)
            {
                _countPerPageTextBox.ContextMenu = null;
                _countPerPageTextBox.PreviewTextInput += _countPerPageTextBox_PreviewTextInput;
                _countPerPageTextBox.PreviewKeyDown += _countPerPageTextBox_PreviewKeyDown;
            }

            _jumpPageTextBox = GetTemplateChild(JustPageTextBoxTemplateName) as TextBox;
            if (_jumpPageTextBox != null)
            {
                _jumpPageTextBox.ContextMenu = null;
                _jumpPageTextBox.PreviewTextInput += _countPerPageTextBox_PreviewTextInput;
                _jumpPageTextBox.PreviewKeyDown += _countPerPageTextBox_PreviewKeyDown;
            }

            _listBox = GetTemplateChild(ListBoxTemplateName) as ListBox;

            Init();

            SubscribeEvents();
        }

        private void _countPerPageTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (Key.Space == e.Key
                ||
                Key.V == e.Key
                && e.KeyboardDevice.Modifiers == ModifierKeys.Control)
                e.Handled = true;
        }

        private void _countPerPageTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            //e.Handled = ControlsHelper.IsNumber(e.Text);
        }

        #endregion

        #region Command

        private static void InitializeCommands()
        {

            PrevCommand = new RoutedCommand("Prev", _typeofSelf);
            NextCommand = new RoutedCommand("Next", _typeofSelf);

            CommandManager.RegisterClassCommandBinding(_typeofSelf,
                new CommandBinding(PrevCommand, OnPrevCommand, OnCanPrevCommand));
            CommandManager.RegisterClassCommandBinding(_typeofSelf,
                new CommandBinding(NextCommand, OnNextCommand, OnCanNextCommand));
        }

        public static RoutedCommand PrevCommand { get; private set; }

        public static RoutedCommand NextCommand { get; private set; }

        private static void OnPrevCommand(object sender, RoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            ctrl.Current--;
        }

        private static void OnCanPrevCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            e.CanExecute = ctrl.Current > 1;
        }

        private static void OnNextCommand(object sender, RoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            ctrl.Current++;
        }

        private static void OnCanNextCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            var ctrl = sender as Pagination;
            e.CanExecute = ctrl.Current < ctrl.PageCount;
        }

        #endregion

        #region Properties



        public ImageSource LeftIcon
        {
            get { return (ImageSource)GetValue(LeftIconProperty); }
            set { SetValue(LeftIconProperty, value); }
        }

        // Using a DependencyProperty as the backing store for LeftIcon.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LeftIconProperty =
            DependencyProperty.Register("LeftIcon", typeof(ImageSource), typeof(Pagination), new PropertyMetadata(null));



        public ImageSource RightIcon
        {
            get { return (ImageSource)GetValue(RightIconProperty); }
            set { SetValue(RightIconProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RightIcon.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RightIconProperty =
            DependencyProperty.Register("RightIcon", typeof(ImageSource), typeof(Pagination), new PropertyMetadata(null));




        private static readonly DependencyPropertyKey PagesPropertyKey =
            DependencyProperty.RegisterReadOnly("Pages", typeof(IEnumerable<string>), _typeofSelf,
                new PropertyMetadata(null));

        public static readonly DependencyProperty PagesProperty = PagesPropertyKey.DependencyProperty;

        public IEnumerable<string> Pages => (IEnumerable<string>)GetValue(PagesProperty);

        private static readonly DependencyPropertyKey PageCountPropertyKey =
            DependencyProperty.RegisterReadOnly("PageCount", typeof(int), _typeofSelf,
                new PropertyMetadata(1, OnPageCountPropertyChanged));

        public static readonly DependencyProperty PageCountProperty = PageCountPropertyKey.DependencyProperty;

        public int PageCount => (int)GetValue(PageCountProperty);

        private static void OnPageCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as Pagination;
            var pageCount = (int)e.NewValue;

            /*
            if (ctrl._jumpPageTextBox != null)
                ctrl._jumpPageTextBox.Maximum = pageCount;
            */
        }

        public static readonly DependencyProperty IsLiteProperty =
            DependencyProperty.Register("IsLite", typeof(bool), _typeofSelf, new PropertyMetadata(false));

        public bool IsLite
        {
            get => (bool)GetValue(IsLiteProperty);
            set => SetValue(IsLiteProperty, value);
        }

        public static readonly DependencyProperty CountProperty = DependencyProperty.Register("Count", typeof(int),
            _typeofSelf, new PropertyMetadata(0, OnCountPropertyChanged, CoerceCount));

        public int Count
        {
            get => (int)GetValue(CountProperty);
            set => SetValue(CountProperty, value);
        }

        private static object CoerceCount(DependencyObject d, object value)
        {
            var count = (int)value;
            return Math.Max(count, 0);
        }

        private static void OnCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as Pagination;
            var count = (int)e.NewValue;

            ctrl.SetValue(PageCountPropertyKey, (int)Math.Ceiling(count * 1.0 / ctrl.CountPerPage));
            ctrl.UpdatePages();
        }

        public static readonly DependencyProperty CountPerPageProperty = DependencyProperty.Register("CountPerPage",
            typeof(int), _typeofSelf, new PropertyMetadata(50, OnCountPerPagePropertyChanged, CoerceCountPerPage));

        public int CountPerPage
        {
            get => (int)GetValue(CountPerPageProperty);
            set => SetValue(CountPerPageProperty, value);
        }

        private static object CoerceCountPerPage(DependencyObject d, object value)
        {
            var countPerPage = (int)value;
            return Math.Max(countPerPage, 1);
        }

        private static void OnCountPerPagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as Pagination;
            var countPerPage = (int)e.NewValue;

            if (ctrl._countPerPageTextBox != null)
                ctrl._countPerPageTextBox.Text = countPerPage.ToString();

            ctrl.SetValue(PageCountPropertyKey, (int)Math.Ceiling(ctrl.Count * 1.0 / countPerPage));

            if (ctrl.Current != 1)
                ctrl.Current = 1;
            else
                ctrl.UpdatePages();
        }

        public static readonly DependencyProperty CurrentProperty = DependencyProperty.Register("Current", typeof(int),
            _typeofSelf, new PropertyMetadata(1, OnCurrentPropertyChanged, CoerceCurrent));

        public int Current
        {
            get => (int)GetValue(CurrentProperty);
            set => SetValue(CurrentProperty, value);
        }

        private static object CoerceCurrent(DependencyObject d, object value)
        {
            var current = (int)value;
            var ctrl = d as Pagination;

            return Math.Max(current, 1);
        }

        private static void OnCurrentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as Pagination;
            var current = (int)e.NewValue;

            if (ctrl._listBox != null)
                ctrl._listBox.SelectedItem = current.ToString();

            if (ctrl._jumpPageTextBox != null)
                ctrl._jumpPageTextBox.Text = current.ToString();

            ctrl.UpdatePages();
        }

        #endregion

        #region Event

        /// <summary>
        ///     分页
        /// </summary>
        private void OnCountPerPageTextBoxChanged(object sender, TextChangedEventArgs e)
        {
            if (int.TryParse(_countPerPageTextBox.Text, out var _ountPerPage))
                CountPerPage = _ountPerPage;
        }

        /// <summary>
        ///     跳转页
        /// </summary>
        private void OnJumpPageTextBoxChanged(object sender, TextChangedEventArgs e)
        {
            if (int.TryParse(_jumpPageTextBox.Text, out var _current))
                Current = _current;
        }

        /// <summary>
        ///     选择页
        /// </summary>
        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (_listBox.SelectedItem == null)
                return;

            Current = int.Parse(_listBox.SelectedItem.ToString());
        }

        #endregion

        #region Private

        private void Init()
        {
            SetValue(PageCountPropertyKey, (int)Math.Ceiling(Count * 1.0 / CountPerPage));

            _jumpPageTextBox.Text = Current.ToString();
            //_jumpPageTextBox.Maximum = PageCount;

            _countPerPageTextBox.Text = CountPerPage.ToString();

            if (_listBox != null)
                _listBox.SelectedItem = Current.ToString();
        }

        private void UnsubscribeEvents()
        {
            if (_countPerPageTextBox != null)
                _countPerPageTextBox.TextChanged -= OnCountPerPageTextBoxChanged;

            if (_jumpPageTextBox != null)
                _jumpPageTextBox.TextChanged -= OnJumpPageTextBoxChanged;

            if (_listBox != null)
                _listBox.SelectionChanged -= OnSelectionChanged;
        }

        private void SubscribeEvents()
        {
            if (_countPerPageTextBox != null)
                _countPerPageTextBox.TextChanged += OnCountPerPageTextBoxChanged;

            if (_jumpPageTextBox != null)
                _jumpPageTextBox.TextChanged += OnJumpPageTextBoxChanged;

            if (_listBox != null)
                _listBox.SelectionChanged += OnSelectionChanged;
        }

        private void UpdatePages()
        {
            SetValue(PagesPropertyKey, GetPagers(Count, Current));

            if (_listBox != null && _listBox.SelectedItem == null)
                _listBox.SelectedItem = Current.ToString();
        }

        private IEnumerable<string> GetPagers(int count, int current)
        {
            if (count == 0)
                return null;

            if (PageCount <= 7)
                return Enumerable.Range(1, PageCount).Select(p => p.ToString()).ToArray();

            if (current <= 4)
                return new[] { "1", "2", "3", "4", "5", Ellipsis, PageCount.ToString() };

            if (current >= PageCount - 3)
                return new[]
                {
                    "1", Ellipsis, (PageCount - 4).ToString(), (PageCount - 3).ToString(), (PageCount - 2).ToString(),
                    (PageCount - 1).ToString(), PageCount.ToString()
                };

            return new[]
            {
                "1", Ellipsis, (current - 1).ToString(), current.ToString(), (current + 1).ToString(), Ellipsis,
                PageCount.ToString()
            };
        }

        #endregion
    }

xaml页面调用分页控件

                    <custom:Pagination
                        Grid.Column="1"
                        Width="400"
                        HorizontalAlignment="Left"
                        Count="{Binding Count, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                        CountPerPage="{Binding CountPerPage, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                        Current="{Binding Current, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                        LeftIcon="pack://application:,,,/Images/ic_zuo@2x.png"
                        RightIcon="pack://application:,,,/Images/ic_you@2x.png"
                        Style="{StaticResource NPPagination}" />

与之绑定的要翻页的容器如listbox

<ListBox
                    Height="200"
                    Padding="0"
                    Background="Transparent"
                    BorderBrush="Transparent"
                    ItemContainerStyle="{StaticResource ListBoxItem_MousePointer}"
                    ItemsSource="{Binding MousePointerCollections, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                    ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel Background="Transparent" Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                </ListBox>

ViewModel部分

private int _count;
        public int Count
        {
            get { return _count; }
            set { _count = value; this.RaisePropertyChanged("Count"); CurrentPageChanged(); }
        }

        private int _countPerPage = 4;
        public int CountPerPage
        {
            get { return _countPerPage; }
            set { _countPerPage = value; this.RaisePropertyChanged("CountPerPage"); CurrentPageChanged(); }
        }

        private int _current = 1;
        public int Current
        {
            get { return _current; }
            set { _current = value; this.RaisePropertyChanged("Current"); CurrentPageChanged(); }
        }

        private void CurrentPageChanged()
        {

            MousePointerCollections.Clear();

            foreach (var i in _sourceList.Skip((Current - 1) * CountPerPage).Take(CountPerPage))
            {

                MousePointerCollections.Add(i);
            }
        }
public ObservableCollection<MousePointerCollection> MousePointerCollections { get; set; } = new ObservableCollection<MousePointerCollection>();