WPF 控件【V】VisualBrush (一) VisualBrush 自定义按钮+自定义矢量图标的实现

 

三个例子中,有5个公用文件,主要体现在ImageButtonStyle的不同:

MainWindow.XAML

<Window x:Class="自定义按钮_自定义图标.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:自定义按钮_自定义图标"
        mc:Ignorable="d"
        Title="MainWindow" Height="650" Width="725">
    <StackPanel>
        <local:ImageButton Width="120" Height="130" Content="{DynamicResource Canvas1}" x:Name="btn1" Click="ImageButton_Click"/>
        <local:ImageButton Width="120" Height="140" Content="{DynamicResource Canvas2}" x:Name="btn2" Click="ImageButton_Click" />
        <Button Content="主题1(单击切换)" Click="Button_Click_1"/>
        <Button Content="主题2(单击切换)" Click="Button_Click"/>
        <WrapPanel>
            <Label>更改图标大小</Label>
            <Slider Minimum="120" Maximum="300" TickFrequency="10" ValueChanged="Slider_ValueChanged" Name="slider1" Width="100"/>
        </WrapPanel>
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 自定义按钮_自定义图标
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        ResourceDictionary Theme1 = new ResourceDictionary();
        ResourceDictionary Theme2 = new ResourceDictionary();

        public MainWindow()
        {
            InitializeComponent();

            Theme1.Source = new Uri("IconStyle.xaml", UriKind.Relative);
            Theme2.Source = new Uri("IconStyle2.xaml",UriKind.Relative);
        }

        private void ImageButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hello World");
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Resources.MergedDictionaries[0] = Theme2;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            Application.Current.Resources.MergedDictionaries[0] = Theme1;
        }

        private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            this.btn1.Width = this.slider1.Value;
            this.btn1.Height = this.slider1.Value + 10;
            this.btn2.Width = this.slider1.Value;
            this.btn2.Height = this.slider1.Value + 20;

        }
    }
}

ImageButton.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace 自定义按钮_自定义图标
{
    class ImageButton : System.Windows.Controls.Button
    {
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("ButtonImage", typeof(string), typeof(FrameworkElement));


        static ImageButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
        }

        public string Text
        {
            set
            {
                SetValue(TextProperty, value);
            }
            get
            {
                return (string)GetValue(TextProperty);
            }
        }
    }
}

IconStyle2.XAML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:自定义按钮_自定义图标">
    <Canvas x:Shared="False" x:Key="Canvas1" HorizontalAlignment="Center" Height="52" UseLayoutRounding="False" VerticalAlignment="Center" Width="122">
        <Path Stretch="Fill" Stroke="#FF507EC1" StrokeThickness="2" Canvas.Left="48.663" Canvas.Top="11.332" >
            <Path.Data>
                <PathGeometry>
                    <PathFigure IsFilled="False" StartPoint="19.8707102602993,25.6596382792873">
                        <BezierSegment IsSmoothJoin="True" Point3="2.70087075233459,20.3821029663086" Point2="6.11566352844238,26.3567733764648" Point1="13.6378736495972,28.6688919067383"/>
                        <BezierSegment IsSmoothJoin="True" Point3="6.97411251068115,3.09518456459045" Point2="1.15821123123169,6.83392953872681" Point1="-0.713922142982483,14.4074325561523"/>
                        <BezierSegment IsSmoothJoin="True" Point3="24.6657028198242,6.262038230896" Point2="20.5408058166504,0.743857204914093" Point1="12.7900133132935,-0.643561065196991"/>
                        <BezierSegment Point3="22.5525512695313,23.935619354248" Point2="27.8648147583008,19.523120880127" Point1="28.790599822998,11.780219078064"/>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>
        <Path Data="M265.75,196.125 C268.33333,196.125 270.91667,196.125 273.5,196.125" HorizontalAlignment="Right" Height="3" Stretch="Fill" Stroke="#FF507EC1" StrokeThickness="2" VerticalAlignment="Bottom" Width="10.738" RenderTransformOrigin="0.518,0.614" Canvas.Top="35.75" Canvas.Left="69.25">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleY="-1"/>
                    <SkewTransform AngleX="-3.051"/>
                    <RotateTransform Angle="45.196"/>
                    <TranslateTransform X="0.142" Y="-0.564"/>
                </TransformGroup>
            </Path.RenderTransform>
        </Path>
    </Canvas>

    <Canvas x:Shared="False" x:Key="Canvas2" HorizontalAlignment="Center" Height="36" UseLayoutRounding="False" VerticalAlignment="Center" Width="36">
        <Path Stroke="#FF1DBBD8" Height="21.448" Canvas.Left="4.329" Canvas.Top="5.1" Width="29.973" StrokeThickness="0" RenderTransformOrigin="0.5,0.5" Fill="Black" Data="M0.86653168,-1.6160916 L25.834147,-15.423779 31.638699,7.7291467 -2.1097645,8.7246775 z" Stretch="Fill">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="0.134"/>
                    <TranslateTransform X="-0.017363644821621449" Y="0.0027031608210705826"/>
                </TransformGroup>
            </Path.RenderTransform>
        </Path>
        <Path Stroke="#FF1DBBD8" Height="21.896" Canvas.Left="-0.51" Canvas.Top="2.636" Width="16.269" StrokeThickness="0" RenderTransformOrigin="0.5,0.5" Fill="#FF747474" Data="M26.570403,-12.323374 L31.192641,5.1983645 7.9231448,18.979614" Stretch="Fill">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="-149.522"/>
                    <TranslateTransform X="9.0890947131717326" Y="-3.1484694974636085"/>
                </TransformGroup>
            </Path.RenderTransform>
        </Path>
        <Rectangle Stroke="#FF1DBBD8" Height="7.006" Canvas.Left="3.891" Canvas.Top="24.281" Width="31.086" StrokeThickness="1.5" RenderTransformOrigin="0.5,0.5" RadiusX="3" RadiusY="3" Fill="Black" >
            <Rectangle.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="180"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>

    <Canvas Grid.Row="3" Grid.Column="19" Width="60" Height="60" x:Key="backgroud1">
        <Path Data="M0.5,5.5 C0.5,2.7385763 2.7385763,0.5 5.5,0.5 L116.5,0.5 C119.26142,0.5 121.5,2.7385763 121.5,5.5 L121.5,46.5 C121.5,49.261424 119.26142,51.5 116.5,51.5 L5.5,51.5 C2.7385763,51.5 0.5,49.261424 0.5,46.5 z" HorizontalAlignment="Left" Height="60"  Stretch="Fill" Stroke="#FFCDCDCD" VerticalAlignment="Bottom" Width="60" >
            <Path.Fill>
                <LinearGradientBrush EndPoint="0.5,1" Opacity="0.99" StartPoint="0.5,0">
                    <GradientStop Color="#FFDCE0E3" Offset="0.456"/>
                    <GradientStop Color="#FFD8DDE0" Offset="0.828"/>
                    <GradientStop Color="White" Offset="0.033"/>
                    <GradientStop Color="White" Offset="0.979"/>
                </LinearGradientBrush>
            </Path.Fill>
        </Path>
    </Canvas>
</ResourceDictionary>

IconStyle.XAML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:自定义按钮_自定义图标">
    <Canvas x:Shared="False" x:Key="Icon.Open" HorizontalAlignment="Center" Height="33.7549" UseLayoutRounding="False" VerticalAlignment="Center" Width="43.5">
        <Path Data="F1M22.75,0L19.15,5.251 0,5.25 0,28.504 0.75,28.504 7.501,10.501 35.255,10.501 35.255,0z" Fill="White" Height="28.504" Canvas.Left="0.75" Canvas.Top="0.75" Width="35.255"/>
        <Path Clip="M0,0L43.505,0 43.505,33.755 0,33.755z" Data="M19.1,5.251C14.544,5.251 5.2,5.239 0.75,5.251 0.485,5.251 0,5.736 0,6.001L0,33.755 36.755,33.755 43.505,11.251 36.755,11.251 36.755,0 24,0C22.204,0,20.895,5.251,19.1,5.251 M24.4,0.751L35.254,0.751C35.519,0.751,36.005,1.235,36.005,1.501L36.005,11.251C36.005,11.251 15.263,11.239 8.251,11.251 7.729,11.252 6.656,12.614 6.356,13.052 3.981,16.521 1.5,29.254 1.5,29.254L0.75,29.254 0.75,6.751C0.75,6.486,1.235,6.001,1.5,6.001L19.8,6.001C21.595,6.001,22.604,0.751,24.4,0.751" Fill="#FFECBF7C" Height="33.755" Canvas.Left="0" Canvas.Top="0" Width="43.5"/>
    </Canvas>

    <Canvas x:Shared="False" x:Key="Icon.Save" HorizontalAlignment="Center" Height="20" UseLayoutRounding="False" VerticalAlignment="Center" Width="20">
        <Path Data="F1M0,0L0,9.824 0.351,10.175 14.036,10.175 14.387,9.824 14.387,0z" Fill="White" Height="10.175" Canvas.Left="2.807" Canvas.Top="0.702" Width="14.387"/>
        <Path Data="F1M0.351,0L0,0.35 0,5.262 0.351,5.614 1.404,5.614 3.509,5.614 9.123,5.614 9.474,5.262 9.474,0.35 9.123,0z" Fill="White" Height="5.614" Canvas.Left="4.561" Canvas.Top="13.685" Width="9.474"/>
        <Path Data="F1M0,0L0,18.597 1.404,20 20,20 20,0z M2.807,10.526L2.807,0.702 17.194,0.702 17.194,10.526 16.843,10.877 3.158,10.877z M4.561,18.947L4.561,14.035 4.912,13.684 13.684,13.684 14.036,14.035 14.036,18.947 13.684,19.299 8.07,19.299 8.07,14.738 7.719,14.387 6.316,14.387 5.965,14.738 5.965,19.299 4.912,19.299z" Fill="#FF9263A9" Height="20" Canvas.Left="0" Canvas.Top="0" Width="20"/>
    </Canvas>
</ResourceDictionary>

APP.XAML

<Application x:Class="自定义按钮_自定义图标.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:自定义按钮_自定义图标"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="IconStyle2.xaml"/>
                <ResourceDictionary Source="ImageButtonStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
        
    </Application.Resources>
</Application>

 

 

 

不同的部分在于ImageButtonStyle。

例1 :

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:自定义按钮_自定义图标">
    <Style TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Grid MinHeight="{TemplateBinding MinHeight}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                    <Border x:Name="ViewBoxInternal" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsEnabled="{TemplateBinding IsEnabled}"
                                 Margin="5" Effect="{x:Null}"  BorderThickness="1">
                            <ContentPresenter ContentSource="{TemplateBinding Content}" Width="Auto" Height="Auto" 
                                              HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>

                        <TextBlock x:Name="TextBlockInternal" Grid.Row="0" Margin="2,0"
                                   HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding Text,RelativeSource={RelativeSource TemplatedParent}}"
                                    Effect="{TemplateBinding Effect}" TextAlignment="Center"/>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="True">
                            <Setter Property="Background" TargetName="ViewBoxInternal">
                                <Setter.Value>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="Black" Offset="0.544"/>
                                        <GradientStop Color="#FFFF0057" Offset="1"/>
                                        <GradientStop Color="#FF0909D9" Offset="0.025"/>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" TargetName="ViewBoxInternal">
                                <Setter.Value>
                                    <LinearGradientBrush EndPoint="0.5,1" Opacity="0.99" StartPoint="0.5,0">
                                        <GradientStop Color="#FF1D79C0" Offset="0.456"/>
                                        <GradientStop Color="#FFD8DDE0" Offset="0.828"/>
                                        <GradientStop Color="White" Offset="0.033"/>
                                        <GradientStop Color="#FFFF00CA" Offset="0.979"/>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

例2:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:自定义按钮_自定义图标">

    <Style TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Grid MinHeight="{TemplateBinding MinHeight}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Border x:Name="ViewBoxInternal" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsEnabled="{TemplateBinding IsEnabled}"
                                 Margin="5" Effect="{x:Null}"  BorderThickness="1">
                            <ContentPresenter ContentSource="{TemplateBinding Content}" Width="Auto" Height="Auto" 
                                              HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="True">
                            <Setter Property="Background" TargetName="ViewBoxInternal">
                                <Setter.Value>
                                    <VisualBrush>
                                        <VisualBrush.Visual>
                                            <Canvas  Width="60" Height="60">
                                                <Path Data="M0.5,5.5 C0.5,2.7385763 2.7385763,0.5 5.5,0.5 L116.5,0.5 C119.26142,0.5 121.5,2.7385763 121.5,5.5 L121.5,46.5 C121.5,49.261424 119.26142,51.5 116.5,51.5 L5.5,51.5 C2.7385763,51.5 0.5,49.261424 0.5,46.5 z" HorizontalAlignment="Left" Height="60"  Stretch="Fill" Stroke="#FFCDCDCD" VerticalAlignment="Bottom" Width="60" >
                                                    <Path.Fill>
                                                        <LinearGradientBrush EndPoint="0.5,1" Opacity="0.99" StartPoint="0.5,0">
                                                            <GradientStop Color="#FFDCE0E3" Offset="0.456"/>
                                                            <GradientStop Color="#FFD8DDE0" Offset="0.828"/>
                                                            <GradientStop Color="White" Offset="0.033"/>
                                                            <GradientStop Color="White" Offset="0.979"/>
                                                        </LinearGradientBrush>
                                                    </Path.Fill>
                                                </Path>
                                                <Path Fill="#FF4E7BBF" Stroke="#FF4E7BBF" Data="M15.635766,12.398059 L2.1590548,26.947 20.794333,26.322944 20.829122,26.006824 C20.891917,25.36782 20.917535,24.724717 20.90557,24.084056 20.886434,23.059325 20.770976,22.031934 20.561711,21.028616 20.353166,20.02875 20.049611,19.044074 19.657832,18.100819 19.268443,17.163319 18.788415,16.258458 18.228992,15.41136 17.674008,14.570982 17.035815,13.779892 16.330283,13.061236 16.155425,12.883127 15.976024,12.709057 15.792396,12.53934 z M25.178,0.5 L25.973983,1.237319 16.31553,11.664213 16.563972,11.891166 C17.11272,12.406446 17.630298,12.963342 18.112046,13.559597 20.906182,17.017879 22.235484,21.47905 21.84024,25.936477 L21.804252,26.289123 36.48083,25.797635 36.589637,29.046813 0.60880852,30.251737 0.5,27.002559 1.1887808,26.979493 0.89880466,26.710887 14.802926,11.700531 14.642484,11.575775 C14.443233,11.424722 14.240396,11.278647 14.034291,11.137866 13.216546,10.579294 12.339551,10.098781 11.427907,9.7119775 10.521977,9.3275981 9.5729895,9.0320692 8.6087408,8.8353969 7.6477938,8.6393989 6.662179,8.5396757 5.681447,8.5396752 L5.681447,7.5396753 C9.1289911,7.5396757 12.44958,8.6782074 15.189513,10.735553 L15.485185,10.96399 z" Height="30.752" Canvas.Left="11.165" RenderTransformOrigin="0.153181541693268,0.793196689910506" Stretch="Fill" Canvas.Top="12.738" Width="37.089">
                                                    <Path.RenderTransform>
                                                        <TransformGroup>
                                                            <ScaleTransform/>
                                                            <SkewTransform/>
                                                            <RotateTransform Angle="1.891"/>
                                                            <TranslateTransform/>
                                                        </TransformGroup>
                                                    </Path.RenderTransform>
                                                </Path>
                                            </Canvas>
                                         </VisualBrush.Visual>
                                    </VisualBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" TargetName="ViewBoxInternal">
                                <Setter.Value>
                                    <LinearGradientBrush EndPoint="0.5,1" Opacity="0.99" StartPoint="0.5,0">
                                        <GradientStop Color="#FF1D79C0" Offset="0.456"/>
                                        <GradientStop Color="#FFD8DDE0" Offset="0.828"/>
                                        <GradientStop Color="White" Offset="0.033"/>
                                        <GradientStop Color="#FFFF00CA" Offset="0.979"/>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
   </Style>
</ResourceDictionary>

例子2中,可以将Canvas内的数据独立放在一个文件,利用VisualBrush 实现动态的调用。比如:

 

 

 

例3:

 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:自定义按钮_自定义图标">
    <Style TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Border Name="border" BorderThickness="0" BorderBrush="Transparent">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Border>
                    
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="True">
                            <Setter Property="Background" TargetName="border">
                                <Setter.Value>
                                    <VisualBrush Visual="{Binding  Path=DefaultImage, RelativeSource={RelativeSource TemplatedParent}}"></VisualBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" TargetName="border">
                                <Setter.Value>
                                    <VisualBrush Visual="{Binding  Path=PressedImage, RelativeSource={RelativeSource TemplatedParent}}"></VisualBrush>
                                </Setter.Value>
                            </Setter>
                          </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值