WPF自定义分页控件Pagination

改造他人的分页控件,先看效果图

主要代码有两个,Pagination.cs ,Pagination.xaml,其中用到了第三方开源控件HandyControl的样式

Pagination.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace King_E.ARMS.Client.UserControls.Pagination
{
    [TemplatePart(Name = CountPerPageComboBoxTemplateName, Type = typeof(ComboBox))]
    [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 CountPerPageComboBoxTemplateName = "PART_CountPerPageCount";
        private const string JustPageTextBoxTemplateName = "PART_JumpPageTextBox";
        private const string ListBoxTemplateName = "PART_ListBox";
        private const string Ellipsis = "...";
        private static readonly Type _typeofSelf = typeof(Pagination);
        private ComboBox _countPerPageComboBox;
        private TextBox _jumpPageTextBox;
        private ListBox _listBox;
        static Pagination()
        {
            InitializeCommands();
            DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf));
        }

        #region Override
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            UnsubscribeEvents();

            _countPerPageComboBox = GetTemplateChild(CountPerPageComboBoxTemplateName) as ComboBox;
            if (_countPerPageComboBox != null)
            {
                _countPerPageComboBox.ContextMenu = null;
            }

            _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 = true;// 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

        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 PageRecordCountPropertyKey =
            DependencyProperty.RegisterReadOnly("PageRecordCount", typeof(IEnumerable<int>), _typeofSelf,
        new PropertyMetadata(null));

        public static readonly DependencyProperty PageRecordCountProperty = PageRecordCountPropertyKey.DependencyProperty;

        public IEnumerable<int> PageRecordCount
        {
            get => (IEnumerable<int>)GetValue(PageRecordCountProperty);
            set {
                SetValue(PageRecordCountProperty, value);
            }
        }

        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(10, OnCountPerPagePropertyChanged, CoerceCountPerPage));

        public int CountPerPage
        {
            get => (int)GetValue(CountPerPageProperty);
            set
            {
                SetValue(CountPerPageProperty, value);
                RaiseCountPerPageChangedEvent(value);
                RaiseCurrentPageChangedEvent(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._countPerPageComboBox != null)
                ctrl._countPerPageComboBox.SelectedItem = countPerPage;

            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);
                RaiseCurrentPageChangedEvent(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
        // 定义事件声明
        public static readonly RoutedEvent CountPerPageChangedEvent = EventManager.RegisterRoutedEvent(
            "CountPerPageChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), _typeofSelf);

        // 属性包装事件
        public event RoutedEventHandler CountPerPageChanged
        {
            add { AddHandler(CountPerPageChangedEvent, value); }
            remove { RemoveHandler(CountPerPageChangedEvent, value); }
        }

        // 触发事件的方法
        public void RaiseCountPerPageChangedEvent(object source)
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(CountPerPageChangedEvent,source);
            RaiseEvent(newEventArgs);
        }

        // 定义事件声明
        public static readonly RoutedEvent CurrentPageChangedEvent = EventManager.RegisterRoutedEvent(
            "CurrentPageChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), _typeofSelf);

        // 属性包装事件
        public event RoutedEventHandler CurrentPageChanged
        {
            add { AddHandler(CurrentPageChangedEvent, value); }
            remove { RemoveHandler(CurrentPageChangedEvent, value); }
        }

        // 触发事件的方法
        public void RaiseCurrentPageChangedEvent(object source)
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(CurrentPageChangedEvent,source);
            RaiseEvent(newEventArgs);
        }
        /// <summary>
        /// 分页
        /// </summary>
        private void OnCountPerPageComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (int.TryParse(_countPerPageComboBox.SelectedItem.ToString(), 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;
            _countPerPageComboBox.SelectedItem = CountPerPage;
            if (_listBox != null)
                _listBox.SelectedItem = Current.ToString();
        }

        private void UnsubscribeEvents()
        {
            if (_countPerPageComboBox != null)
                _countPerPageComboBox.SelectionChanged -= OnCountPerPageComboBoxSelectionChanged;

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

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

        private void SubscribeEvents()
        {
            if (_countPerPageComboBox != null)
                _countPerPageComboBox.SelectionChanged += OnCountPerPageComboBoxSelectionChanged;

            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

    }
}
 

Pagination.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib"
                    xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
                    xmlns:controls="clr-namespace:King_E.ARMS.Client.UserControls.Pagination">

    <x:Array Type="{x:Type sys:Int32}" x:Key="IEnumerableInts">
        <sys:Int32>10</sys:Int32>
        <sys:Int32>15</sys:Int32>
        <sys:Int32>20</sys:Int32>
        <sys:Int32>25</sys:Int32>
        <sys:Int32>30</sys:Int32>
        <sys:Int32>40</sys:Int32>
        <sys:Int32>50</sys:Int32>
        <sys:Int32>100</sys:Int32>
        <sys:Int32>200</sys:Int32>
        <sys:Int32>300</sys:Int32>
    </x:Array>

    <Style x:Key="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 BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}" 
                            Background="{TemplateBinding Background}" 
                            SnapsToDevicePixels="True">
                        <ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}">
                            <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="PageListBoxItemStyleKey" 
           TargetType="{x:Type ListBoxItem}" >
        <Setter Property="Width" Value="28"/>
        <Setter Property="Height" Value="28"/>
        <Setter Property="Cursor" Value="Hand"/>
        <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="{StaticResource BackgroundBrush}"/>
        <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border SnapsToDevicePixels="True"
                            Background="{TemplateBinding Background}" 
                            BorderThickness="{TemplateBinding BorderThickness}" 
                            BorderBrush="{TemplateBinding BorderBrush}"  
                            Padding="{TemplateBinding Padding}"
                            CornerRadius="3">

                        <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="{StaticResource BorderBrush}"/>
                <Setter Property="Background" Value="{StaticResource PrimaryBrush}"/>
                <Setter Property="Foreground" Value="White"/>
            </Trigger>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="{StaticResource PrimaryBrush}"/>
                <Setter Property="TextElement.Foreground" Value="White"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    
    <ControlTemplate x:Key="LitePagerControlTemplate" TargetType="{x:Type controls:Pagination}">
        <Border Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                Padding="{TemplateBinding Padding}">
            <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}}"/>

                <ComboBox Grid.Column="2" x:Name="PART_CountPerPageCount" 
                          VerticalAlignment="Center"
                          Width="60" VerticalContentAlignment="Center"
                          ItemsSource="{DynamicResource IEnumerableInts}"/>
                <TextBlock Grid.Column="3" Text=" 条 / 页" VerticalAlignment="Center"/>
                <Button Grid.Column="5" Foreground="White"
                        Content="&lt;"
                        Command="{x:Static controls:Pagination.PrevCommand}">                    
                </Button>

                <TextBox Grid.Column="7" x:Name="PART_JumpPageTextBox" 
                         TextAlignment="Center" 
                         VerticalContentAlignment="Center"
                         Width="60" MinWidth="0">
                    <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" Foreground="White"
                        Content="&gt;"
                        Command="{x:Static controls:Pagination.NextCommand}">
                </Button>
            </Grid>
        </Border>
    </ControlTemplate>

    <Style TargetType="{x:Type controls:Pagination}" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:Pagination}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Padding="{TemplateBinding Padding}">
                        <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}}"/>
                            <StackPanel Grid.Column="1" Orientation="Horizontal" Margin="0,0,15,0" >
                                <TextBlock Text="每页 " VerticalAlignment="Center"/>
                                <ComboBox Grid.Column="2" x:Name="PART_CountPerPageCount" 
                                    VerticalAlignment="Center"
                                    Width="60" VerticalContentAlignment="Center"
                                    ItemsSource="{DynamicResource IEnumerableInts}"/>
                                <TextBlock Text=" 条" VerticalAlignment="Center"/>
                            </StackPanel>
                            <Button Grid.Column="2" Foreground="White"
                                    Content="&lt;"  Style="{StaticResource ButtonPrimary}"
                                    Command="{x:Static controls:Pagination.PrevCommand}">
                            </Button>
                            <ListBox x:Name="PART_ListBox" Grid.Column="3"
                                     SelectedIndex="0" Margin="5,0"
                                     ItemsSource="{TemplateBinding Pages}"
                                     Style="{StaticResource PageListBoxStyleKey}"
                                     ItemContainerStyle="{StaticResource PageListBoxItemStyleKey}"
                                     ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                                     ScrollViewer.VerticalScrollBarVisibility="Hidden">
                                <ListBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <UniformGrid Rows="1"/>
                                    </ItemsPanelTemplate>
                                </ListBox.ItemsPanel>
                            </ListBox>
                            <Button Grid.Column="4" Foreground="White"
                                    Content="&gt;" Style="{StaticResource ButtonPrimary}"
                                    Command="{x:Static controls:Pagination.NextCommand}">
                            </Button>
                            <StackPanel Grid.Column="5" Orientation="Horizontal" Visibility="Hidden">
                                <TextBlock Text=" 前往 " VerticalAlignment="Center"/>
                                <TextBox x:Name="PART_JumpPageTextBox"
                                         TextAlignment="Center" 
                                         ContextMenu="{x:Null}"
                                         Width="60" VerticalContentAlignment="Center"
                                         MinWidth="0"
                                         FontSize="{TemplateBinding FontSize}" />
                                <TextBlock Text=" 页" VerticalAlignment="Center"/>
                            </StackPanel>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsLite" Value="true">
                <Setter Property="Template" Value="{StaticResource LitePagerControlTemplate}"/>
            </Trigger>
        </Style.Triggers>
    </Style>

</ResourceDictionary>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值