首页 > 编程 > C# > 正文

超炫酷的WPF实现Loading控件效果

2019-10-29 21:35:21
字体:
来源:转载
供稿:网友

这篇文章主要介绍了超炫酷的WPF实现Loading控件效果,感兴趣的小伙伴们可以参考一下

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

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

超炫酷的WPF实现Loading控件效果

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

超炫酷的WPF实现Loading控件效果

3、如果报错找不到Loading类型,请编译,下面在Generic.xaml主题文件中对Loading的样式和内容进行定义(注意添加

 

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

在构建中发现,一开始在设定绑定时,写成一直都无法绑定成功,后来查了资料,改成 后成功。

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

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

超炫酷的WPF实现Loading控件效果

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

超炫酷的WPF实现Loading控件效果

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

超炫酷的WPF实现Loading控件效果

7.总结

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

以上就是WPF实现炫酷Loading控件的全部内容,希望对大家的学习有所帮助。


注:相关教程知识阅读请移步到c#教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表