• WPF实现炫酷Loading控件


    Win8系统的Loading效果还是很不错的,网上也有人用CSS3等技术实现,研究了一下,并打算用WPF自定义一个Loading控件实现类似的效果,并可以让用户对Loading的颗粒(Particle)背景颜色进行自定义,话不多说,直接上代码:

    1、用VS2012新建一个WPF的用户控件库项目WpfControlLibraryDemo,VS自动生成如下结构:

    2、删除UserControl1.xaml,并新建一个Loading的CustomControl(不是UserControl),如下图所示:

    3、如果报错找不到Loading类型,请编译,下面在Generic.xaml主题文件中对Loading的样式和内容进行定义(注意添加 xmlns:system = "clr-namespace:System;assembly=mscorlib"),代码如下:

      1 <ResourceDictionary
      2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4      xmlns:system = "clr-namespace:System;assembly=mscorlib"
      5     xmlns:local="clr-namespace:WpfControlLibraryDemo">
      6 
      7 
      8     <Style TargetType="{x:Type local:Loading}">
      9         <Setter Property="Template">
     10             <Setter.Value>
     11                 <ControlTemplate TargetType="{x:Type local:Loading}">
     12                     <Border Background="{TemplateBinding Background}"
     13                             BorderBrush="{TemplateBinding BorderBrush}"
     14                             BorderThickness="{TemplateBinding BorderThickness}">
     15                         <Grid Width = "50" Height = "50">
     16                             <Grid.Resources>
     17                                 <!-- Value Converters -->
     18                            
     19                                 <!-- Particle Styling ,must to has RelativeSource  -->
     20                                 <SolidColorBrush x:Key = "ParticleColor" Color = "{Binding Path=FillColor,RelativeSource={RelativeSource TemplatedParent}}" />
     21                                 <SolidColorBrush x:Key = "ParticleBackgroundColor" Color = "Transparent"/>
     22                                 <system:Double x:Key = "ParticleOpacity">1</system:Double>
     23                                 <system:Double x:Key = "ParticleRadius">5</system:Double>
     24 
     25                                 <system:Double x:Key = "StartingPointX">0</system:Double>
     26                                 <system:Double x:Key = "StartingPointY">-20</system:Double>
     27 
     28                                 <system:Double x:Key = "RotationPointX">0.5</system:Double>
     29                                 <system:Double x:Key = "RotationPointY">0.5</system:Double>
     30 
     31                                 <!-- StoryBoard -->
     32                                 <system:TimeSpan x:Key = "StoryBoardBeginTimeP0">00:00:00.000</system:TimeSpan>
     33                                 <system:TimeSpan x:Key = "StoryBoardBeginTimeP1">00:00:00.100</system:TimeSpan>
     34                                 <system:TimeSpan x:Key = "StoryBoardBeginTimeP2">00:00:00.200</system:TimeSpan>
     35                                 <system:TimeSpan x:Key = "StoryBoardBeginTimeP3">00:00:00.300</system:TimeSpan>
     36                                 <system:TimeSpan x:Key = "StoryBoardBeginTimeP4">00:00:00.400</system:TimeSpan>
     37                                 <Duration x:Key = "StoryBoardDuration">00:00:01.800</Duration>
     38 
     39                                 <!-- Particle Origin Angles -->
     40                                 <system:Double x:Key = "ParticleOriginAngleP0">0</system:Double>
     41                                 <system:Double x:Key = "ParticleOriginAngleP1">-10</system:Double>
     42                                 <system:Double x:Key = "ParticleOriginAngleP2">-20</system:Double>
     43                                 <system:Double x:Key = "ParticleOriginAngleP3">-30</system:Double>
     44                                 <system:Double x:Key = "ParticleOriginAngleP4">-40</system:Double>
     45 
     46                                 <!-- Particle Position & Timing 1 -->
     47                                 <system:Double x:Key = "ParticleBeginAngle1">0</system:Double>
     48                                 <system:Double x:Key = "ParticleEndAngle1">90</system:Double>
     49                                 <system:TimeSpan x:Key = "ParticleBeginTime1">00:00:00.000</system:TimeSpan>
     50                                 <Duration x:Key = "ParticleDuration1">00:00:00.750</Duration>
     51 
     52                                 <!-- Particle Position & Timing 2 -->
     53                                 <system:Double x:Key = "ParticleBeginAngle2">90</system:Double>
     54                                 <system:Double x:Key = "ParticleEndAngle2">270</system:Double>
     55                                 <system:TimeSpan x:Key = "ParticleBeginTime2">00:00:00.751</system:TimeSpan>
     56                                 <Duration x:Key = "ParticleDuration2">00:00:00.300</Duration>
     57 
     58                                 <!-- Particle Position & Timing 3 -->
     59                                 <system:Double x:Key = "ParticleBeginAngle3">270</system:Double>
     60                                 <system:Double x:Key = "ParticleEndAngle3">360</system:Double>
     61                                 <system:TimeSpan x:Key = "ParticleBeginTime3">00:00:01.052</system:TimeSpan>
     62                                 <Duration x:Key = "ParticleDuration3">00:00:00.750</Duration>
     63 
     64                                 <Style x:Key = "EllipseStyle" TargetType = "Ellipse">
     65                                     <Setter Property = "Width" Value = "{StaticResource ParticleRadius}"/>
     66                                     <Setter Property = "Height" Value = "{StaticResource ParticleRadius}"/>
     67                                     <Setter Property = "Fill" Value = "{StaticResource ParticleColor}"/>
     68                                     <Setter Property = "RenderTransformOrigin" Value = "0.5, 0.5"/>
     69                                     <Setter Property = "Opacity" Value = "{StaticResource ParticleOpacity}"/>
     70                                 </Style>
     71                             </Grid.Resources>
     72                             <Canvas Width = "1" Height = "1" Margin="0,0,0,0">
     73                                 <Canvas.Triggers>
     74                                     <EventTrigger RoutedEvent = "Canvas.Loaded">
     75                                         <EventTrigger.Actions>
     76                                             <BeginStoryboard>
     77                                                 <Storyboard
     78                          
     79                             BeginTime = "{StaticResource StoryBoardBeginTimeP0}"
     80                             Duration = "{StaticResource StoryBoardDuration}"
     81                             RepeatBehavior = "Forever">
     82                                                     <DoubleAnimation
     83                                 Storyboard.TargetName = "p0"
     84                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
     85                                 From = "{StaticResource ParticleBeginAngle1}"
     86                                 To = "{StaticResource ParticleEndAngle1}"
     87                                 BeginTime = "{StaticResource ParticleBeginTime1}"
     88                                 Duration = "{StaticResource ParticleDuration1}"/>
     89                                                     <DoubleAnimation
     90                                 Storyboard.TargetName = "p0"
     91                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
     92                                 From = "{StaticResource ParticleBeginAngle2}"
     93                                 To = "{StaticResource ParticleEndAngle2}"
     94                                 BeginTime = "{StaticResource ParticleBeginTime2}"
     95                                 Duration = "{StaticResource ParticleDuration2}"/>
     96                                                     <DoubleAnimation
     97                                 Storyboard.TargetName = "p0"
     98                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
     99                                 From = "{StaticResource ParticleBeginAngle3}"
    100                                 To = "{StaticResource ParticleEndAngle3}"
    101                                 BeginTime = "{StaticResource ParticleBeginTime3}"
    102                                 Duration = "{StaticResource ParticleDuration3}"/>
    103                                                 </Storyboard>
    104                                             </BeginStoryboard>
    105                                             <BeginStoryboard>
    106                                                 <Storyboard
    107                             
    108                             BeginTime = "{StaticResource StoryBoardBeginTimeP1}"
    109                             Duration = "{StaticResource StoryBoardDuration}"
    110                             RepeatBehavior = "Forever">
    111 
    112                                                     <DoubleAnimation
    113                                 Storyboard.TargetName = "p1"
    114                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    115                                 From = "{StaticResource ParticleBeginAngle1}"
    116                                 To = "{StaticResource ParticleEndAngle1}"
    117                                 BeginTime = "{StaticResource ParticleBeginTime1}"
    118                                 Duration = "{StaticResource ParticleDuration1}"/>
    119                                                     <DoubleAnimation
    120                                 Storyboard.TargetName = "p1"
    121                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    122                                 From = "{StaticResource ParticleBeginAngle2}"
    123                                 To = "{StaticResource ParticleEndAngle2}"
    124                                 BeginTime = "{StaticResource ParticleBeginTime2}"
    125                                 Duration = "{StaticResource ParticleDuration2}"/>
    126                                                     <DoubleAnimation
    127                                 Storyboard.TargetName = "p1"
    128                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    129                                 From = "{StaticResource ParticleBeginAngle3}"
    130                                 To = "{StaticResource ParticleEndAngle3}"
    131                                 BeginTime = "{StaticResource ParticleBeginTime3}"
    132                                 Duration = "{StaticResource ParticleDuration3}"/>
    133                                                 </Storyboard>
    134                                             </BeginStoryboard>
    135                                             <BeginStoryboard>
    136                                                 <Storyboard
    137                             
    138                             BeginTime = "{StaticResource StoryBoardBeginTimeP2}"
    139                             Duration = "{StaticResource StoryBoardDuration}"
    140                             RepeatBehavior = "Forever">
    141 
    142                                                     <DoubleAnimation
    143                                 Storyboard.TargetName = "p2"
    144                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    145                                 From = "{StaticResource ParticleBeginAngle1}"
    146                                 To = "{StaticResource ParticleEndAngle1}"
    147                                 BeginTime = "{StaticResource ParticleBeginTime1}"
    148                                 Duration = "{StaticResource ParticleDuration1}"/>
    149                                                     <DoubleAnimation
    150                                 Storyboard.TargetName = "p2"
    151                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    152                                 From = "{StaticResource ParticleBeginAngle2}"
    153                                 To = "{StaticResource ParticleEndAngle2}"
    154                                 BeginTime = "{StaticResource ParticleBeginTime2}"
    155                                 Duration = "{StaticResource ParticleDuration2}"/>
    156                                                     <DoubleAnimation
    157                                 Storyboard.TargetName = "p2"
    158                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    159                                 From = "{StaticResource ParticleBeginAngle3}"
    160                                 To = "{StaticResource ParticleEndAngle3}"
    161                                 BeginTime = "{StaticResource ParticleBeginTime3}"
    162                                 Duration = "{StaticResource ParticleDuration3}"/>
    163                                                 </Storyboard>
    164                                             </BeginStoryboard>
    165 
    166                                             <BeginStoryboard>
    167                                                 <Storyboard
    168                             
    169                             BeginTime = "{StaticResource StoryBoardBeginTimeP3}"
    170                             Duration = "{StaticResource StoryBoardDuration}"
    171                             RepeatBehavior = "Forever">
    172 
    173                                                     <DoubleAnimation
    174                                 Storyboard.TargetName = "p3"
    175                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    176                                 From = "{StaticResource ParticleBeginAngle1}"
    177                                 To = "{StaticResource ParticleEndAngle1}"
    178                                 BeginTime = "{StaticResource ParticleBeginTime1}"
    179                                 Duration = "{StaticResource ParticleDuration1}"/>
    180                                                     <DoubleAnimation
    181                                 Storyboard.TargetName = "p3"
    182                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    183                                 From = "{StaticResource ParticleBeginAngle2}"
    184                                 To = "{StaticResource ParticleEndAngle2}"
    185                                 BeginTime = "{StaticResource ParticleBeginTime2}"
    186                                 Duration = "{StaticResource ParticleDuration2}"/>
    187                                                     <DoubleAnimation
    188                                 Storyboard.TargetName = "p3"
    189                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    190                                 From = "{StaticResource ParticleBeginAngle3}"
    191                                 To = "{StaticResource ParticleEndAngle3}"
    192                                 BeginTime = "{StaticResource ParticleBeginTime3}"
    193                                 Duration = "{StaticResource ParticleDuration3}"/>
    194                                                 </Storyboard>
    195                                             </BeginStoryboard>
    196 
    197                                             <BeginStoryboard>
    198                                                 <Storyboard
    199                             
    200                             BeginTime = "{StaticResource StoryBoardBeginTimeP4}"
    201                             Duration = "{StaticResource StoryBoardDuration}"
    202                             RepeatBehavior = "Forever">
    203 
    204                                                     <DoubleAnimation
    205                                 Storyboard.TargetName = "p4"
    206                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    207                                 From = "{StaticResource ParticleBeginAngle1}"
    208                                 To = "{StaticResource ParticleEndAngle1}"
    209                                 BeginTime = "{StaticResource ParticleBeginTime1}"
    210                                 Duration = "{StaticResource ParticleDuration1}"/>
    211                                                     <DoubleAnimation
    212                                 Storyboard.TargetName = "p4"
    213                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    214                                 From = "{StaticResource ParticleBeginAngle2}"
    215                                 To = "{StaticResource ParticleEndAngle2}"
    216                                 BeginTime = "{StaticResource ParticleBeginTime2}"
    217                                 Duration = "{StaticResource ParticleDuration2}"/>
    218                                                     <DoubleAnimation
    219                                 Storyboard.TargetName = "p4"
    220                                 Storyboard.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"
    221                                 From = "{StaticResource ParticleBeginAngle3}"
    222                                 To = "{StaticResource ParticleEndAngle3}"
    223                                 BeginTime = "{StaticResource ParticleBeginTime3}"
    224                                 Duration = "{StaticResource ParticleDuration3}"/>
    225                                                 </Storyboard>
    226                                             </BeginStoryboard>
    227                                         </EventTrigger.Actions>
    228                                     </EventTrigger>
    229                                 </Canvas.Triggers>
    230                                 <Border
    231             x:Name = "p0"
    232             Background = "{StaticResource ParticleBackgroundColor}"
    233             Opacity = "{StaticResource ParticleOpacity}">
    234                                     <Border.RenderTransform>
    235                                         <RotateTransform/>
    236                                     </Border.RenderTransform>
    237                                     <Border.RenderTransformOrigin>
    238                                         <Point X = "{StaticResource RotationPointX}" Y = "{StaticResource RotationPointY}"/>
    239                                     </Border.RenderTransformOrigin>
    240                                     <Ellipse Style = "{StaticResource EllipseStyle}">
    241                                         <Ellipse.RenderTransform>
    242                                             <TransformGroup>
    243                                                 <TranslateTransform X = "{StaticResource StartingPointX}" Y = "{StaticResource StartingPointY}"/>
    244                                                 <RotateTransform Angle = "{StaticResource ParticleOriginAngleP0}"/>
    245                                             </TransformGroup>
    246                                         </Ellipse.RenderTransform>
    247                                     </Ellipse>
    248                                 </Border>
    249                                 <Border
    250             x:Name = "p1"
    251             Background = "{StaticResource ParticleBackgroundColor}"
    252             Opacity = "{StaticResource ParticleOpacity}">
    253                                     <Border.RenderTransform>
    254                                         <RotateTransform/>
    255                                     </Border.RenderTransform>
    256                                     <Border.RenderTransformOrigin>
    257                                         <Point X = "{StaticResource RotationPointX}" Y = "{StaticResource RotationPointY}"/>
    258                                     </Border.RenderTransformOrigin>
    259                                     <Ellipse Style = "{StaticResource EllipseStyle}">
    260                                         <Ellipse.RenderTransform>
    261                                             <TransformGroup>
    262                                                 <TranslateTransform X = "{StaticResource StartingPointX}" Y = "{StaticResource StartingPointY}"/>
    263                                                 <RotateTransform Angle = "{StaticResource ParticleOriginAngleP1}"/>
    264                                             </TransformGroup>
    265                                         </Ellipse.RenderTransform>
    266                                     </Ellipse>
    267                                 </Border>
    268                                 <Border
    269             x:Name = "p2"
    270             Background = "{StaticResource ParticleBackgroundColor}"
    271             Opacity = "{StaticResource ParticleOpacity}">
    272                                     <Border.RenderTransform>
    273                                         <RotateTransform/>
    274                                     </Border.RenderTransform>
    275                                     <Border.RenderTransformOrigin>
    276                                         <Point X = "{StaticResource RotationPointX}" Y = "{StaticResource RotationPointY}"/>
    277                                     </Border.RenderTransformOrigin>
    278                                     <Ellipse Style = "{StaticResource EllipseStyle}">
    279                                         <Ellipse.RenderTransform>
    280                                             <TransformGroup>
    281                                                 <TranslateTransform X = "{StaticResource StartingPointX}" Y = "{StaticResource StartingPointY}"/>
    282                                                 <RotateTransform Angle = "{StaticResource ParticleOriginAngleP2}"/>
    283                                             </TransformGroup>
    284                                         </Ellipse.RenderTransform>
    285                                     </Ellipse>
    286                                 </Border>
    287                                 <Border
    288             x:Name = "p3"
    289             Background = "{StaticResource ParticleBackgroundColor}"
    290             Opacity = "{StaticResource ParticleOpacity}">
    291                                     <Border.RenderTransform>
    292                                         <RotateTransform/>
    293                                     </Border.RenderTransform>
    294                                     <Border.RenderTransformOrigin>
    295                                         <Point X = "{StaticResource RotationPointX}" Y = "{StaticResource RotationPointY}"/>
    296                                     </Border.RenderTransformOrigin>
    297                                     <Ellipse Style = "{StaticResource EllipseStyle}">
    298                                         <Ellipse.RenderTransform>
    299                                             <TransformGroup>
    300                                                 <TranslateTransform X = "{StaticResource StartingPointX}" Y = "{StaticResource StartingPointY}"/>
    301                                                 <RotateTransform Angle = "{StaticResource ParticleOriginAngleP3}"/>
    302                                             </TransformGroup>
    303                                         </Ellipse.RenderTransform>
    304                                     </Ellipse>
    305                                 </Border>
    306                                 <Border
    307             x:Name = "p4"
    308             Background = "{StaticResource ParticleBackgroundColor}"
    309             Opacity = "{StaticResource ParticleOpacity}">
    310                                     <Border.RenderTransform>
    311                                         <RotateTransform/>
    312                                     </Border.RenderTransform>
    313                                     <Border.RenderTransformOrigin>
    314                                         <Point X = "{StaticResource RotationPointX}" Y = "{StaticResource RotationPointY}"/>
    315                                     </Border.RenderTransformOrigin>
    316                                     <Ellipse Style = "{StaticResource EllipseStyle}">
    317                                         <Ellipse.RenderTransform>
    318                                             <TransformGroup>
    319                                                 <TranslateTransform X = "{StaticResource StartingPointX}" Y = "{StaticResource StartingPointY}"/>
    320                                                 <RotateTransform Angle = "{StaticResource ParticleOriginAngleP4}"/>
    321                                             </TransformGroup>
    322                                         </Ellipse.RenderTransform>
    323                                     </Ellipse>
    324                                 </Border>
    325                             </Canvas>
    326                         </Grid>
    327 
    328 
    329 
    330                     </Border>
    331                 </ControlTemplate>
    332             </Setter.Value>
    333         </Setter>
    334     </Style>
    335     
    336     
    337     
    338 </ResourceDictionary>

    在构建中发现,一开始在设定绑定时,写成<SolidColorBrush x:Key = "ParticleColor" Color = "{Binding Path=FillColor}" />一直都无法绑定成功,后来查了资料,改成<SolidColorBrush x:Key = "ParticleColor" Color = "{Binding Path=FillColor,RelativeSource={RelativeSource TemplatedParent}}" /> 后成功。

    4、编辑Loading.cs文件,对自定义属性FillColor和逻辑进行编码:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Windows;
     7 using System.Windows.Controls;
     8 using System.Windows.Data;
     9 using System.Windows.Documents;
    10 using System.Windows.Input;
    11 using System.Windows.Media;
    12 using System.Windows.Media.Imaging;
    13 using System.Windows.Navigation;
    14 using System.Windows.Shapes;
    15 
    16 namespace WpfControlLibraryDemo
    17 {
    18     using System.ComponentModel;
    19     /// <summary>
    20     /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
    21     ///
    22     /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
    23     /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    24     /// 元素中:
    25     ///
    26     ///     xmlns:MyNamespace="clr-namespace:WpfControlLibraryDemo"
    27     ///
    28     ///
    29     /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
    30     /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    31     /// 元素中:
    32     ///
    33     ///     xmlns:MyNamespace="clr-namespace:WpfControlLibraryDemo;assembly=WpfControlLibraryDemo"
    34     ///
    35     /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
    36     /// 并重新生成以避免编译错误:
    37     ///
    38     ///     在解决方案资源管理器中右击目标项目,然后依次单击
    39     ///     “添加引用”->“项目”->[浏览查找并选择此项目]
    40     ///
    41     ///
    42     /// 步骤 2)
    43     /// 继续操作并在 XAML 文件中使用控件。
    44     ///
    45     ///     <MyNamespace:Loading/>
    46     ///
    47     /// </summary>
    48     public class Loading : Control
    49     {
    50         static Loading()
    51         {
    52             //重载默认样式
    53             DefaultStyleKeyProperty.OverrideMetadata(typeof(Loading), new FrameworkPropertyMetadata(typeof(Loading)));
    54             //DependencyProperty 注册  FillColor
    55             FillColorProperty = DependencyProperty.Register("FillColor",
    56                 typeof(Color),
    57                 typeof(Loading),
    58                 new UIPropertyMetadata(Colors.DarkBlue,
    59                 new PropertyChangedCallback(OnUriChanged))
    60                 );
    61             //Colors.DarkBlue为控件初始化默认值
    62 
    63         }
    64         //属性变更回调函数
    65         private static void OnUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    66         {
    67             //Border b = (Border)d;
    68             //MessageBox.Show(e.NewValue.ToString());
    69 
    70         }
    71         #region 自定义Fields
    72         // DependencyProperty属性定义   FillColorProperty=FillColor+Property组成
    73         public static readonly DependencyProperty FillColorProperty;
    74         #endregion
    75         //VS设计器属性支持
    76         [Description("背景色"), Category("个性配置"), DefaultValue("#FF668899")]
    77         public Color FillColor
    78         {
    79             //GetValue,SetValue为固定写法,此处一般不建议处理其他逻辑
    80             get { return (Color)GetValue(FillColorProperty); }
    81             set { SetValue(FillColorProperty, value); }
    82         }
    83     }
    84 }

     5、编译,如果无误后,可以添加WPF应用程序WpfAppLoadingTest进行测试(添加项目引用)。

    打开MainWindow.xaml,将Loading控件拖放到设计界面上,如下图所示:

     6、控件颜色修改,选中控件,在属性栏中进行配置即可:

     7.总结

    可以看到WPF自定义控件还是比较容易的,但是难点在于UI的设计,如果需要做的美观,需要美工的参与,而且需要转换成XAML。

     

  • 相关阅读:
    8 pandas模块,多层索引
    7 numpy 傅里叶,提取图片轮廓
    6 DataFrame处理丢失数据--数据清洗
    5 pandas模块,DataFrame类
    4 pandas模块,Series类
    3 numpy模块
    2 线性代数基础
    1 Ipython、Jupyter 入门
    jdk安装与环境变量配置(一劳永逸)
    对jsp可见域的变量感悟
  • 原文地址:https://www.cnblogs.com/isaboy/p/loading.html
Copyright © 2020-2023  润新知