CSLA.NET 6.0.0
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
Csla.Xaml.Shared/BusyAnimation.cs
Go to the documentation of this file.
1#if !XAMARIN && !WINDOWS_UWP
2//-----------------------------------------------------------------------
3// <copyright file="BusyAnimation.cs" company="Marimer LLC">
4// Copyright (c) Marimer LLC. All rights reserved.
5// Website: https://cslanet.com
6// </copyright>
7// <summary>Displays a busy animation.</summary>
8//-----------------------------------------------------------------------
9using System;
10using System.Windows;
11using System.Windows.Controls;
12using System.Windows.Media;
13using System.Windows.Threading;
14using System.ComponentModel;
15using System.Globalization;
16
17namespace Csla.Xaml
18{
22 [TemplatePart(Name = "part1", Type = typeof(FrameworkElement))]
23 [TemplatePart(Name = "part2", Type = typeof(FrameworkElement))]
24 [TemplatePart(Name = "part3", Type = typeof(FrameworkElement))]
25 [TemplatePart(Name = "part4", Type = typeof(FrameworkElement))]
26 [TemplatePart(Name = "part5", Type = typeof(FrameworkElement))]
27 [TemplatePart(Name = "part6", Type = typeof(FrameworkElement))]
28 [TemplatePart(Name = "part7", Type = typeof(FrameworkElement))]
29 [TemplatePart(Name = "part8", Type = typeof(FrameworkElement))]
30 [TemplateVisualState(Name = "normal", GroupName = "CommonStates")]
31 [TemplateVisualState(Name = "state1", GroupName = "CommonStates")]
32 [TemplateVisualState(Name = "state2", GroupName = "CommonStates")]
33 [TemplateVisualState(Name = "state3", GroupName = "CommonStates")]
34 [TemplateVisualState(Name = "state4", GroupName = "CommonStates")]
35 [TemplateVisualState(Name = "state5", GroupName = "CommonStates")]
36 [TemplateVisualState(Name = "state6", GroupName = "CommonStates")]
37 [TemplateVisualState(Name = "state7", GroupName = "CommonStates")]
38 [TemplateVisualState(Name = "state8", GroupName = "CommonStates")]
39 public class BusyAnimation : Control
40 {
41 #region Constants
42
43 private const int NUM_STATES = 8;
44
45 #endregion
46
47 #region Member fields and properties
48
49 private DispatcherTimer _timer;
50 private int _state = -1;
51
55 public static readonly DependencyProperty StepIntervalProperty = DependencyProperty.Register(
56 "StepInterval",
57 typeof(TimeSpan),
58 typeof(BusyAnimation),
59 new PropertyMetadata(
60 TimeSpan.FromMilliseconds(100),
61 (o, e) =>
62 {
63 var busyAnimation = (BusyAnimation)o;
64 busyAnimation.StepInterval = (TimeSpan)e.NewValue;
65 if (busyAnimation._timer != null)
66 busyAnimation._timer.Interval = busyAnimation.StepInterval;
67 }));
68
73 public static readonly DependencyProperty IsRunningProperty = DependencyProperty.Register(
74 "IsRunning",
75 typeof(bool),
76 typeof(BusyAnimation),
77 new PropertyMetadata((o, e) => ((BusyAnimation)o).SetupRunningState((bool)e.NewValue)));
78
83 [Category("Common")]
84 public TimeSpan StepInterval
85 {
86 get { return (TimeSpan)GetValue(StepIntervalProperty); }
87 set
88 {
89 SetValue(StepIntervalProperty, value);
90 }
91 }
92
97 [Category("Common")]
98 public bool IsRunning
99 {
100 get
101 {
102 return (bool)GetValue(IsRunningProperty);
103 }
104 set
105 {
106 SetValue(IsRunningProperty, value);
107 }
108 }
109
110 private void SetupRunningState(bool isRunning)
111 {
112 if (isRunning)
113 StartTimer();
114 else
115 StopTimer();
116
117 GoToState(true);
118 }
119
120 #endregion
121
122 #region Constructor
123
128 {
129 DefaultStyleKey = typeof(BusyAnimation);
130 Loaded += (o, e) =>
131 {
132 ArrangeParts();
133 GoToState(true);
134 };
135 SizeChanged += BusyAnimation_SizeChanged;
136 LayoutUpdated += BusyAnimation_LayoutUpdated;
137 }
138
139 #endregion
140
141 #region Timer
142
143 private void StartTimer()
144 {
145 if (_timer == null)
146 {
147 _timer = new DispatcherTimer();
148 _timer.Interval = StepInterval;
149 _timer.Tick += timer_Tick;
150 _timer.Start();
151 }
152 }
153
154 private void StopTimer()
155 {
156 if (_timer != null)
157 {
158 _timer.Stop();
159 _timer.Tick -= timer_Tick;
160 _timer = null;
161 }
162 }
163
164 void timer_Tick(object sender, EventArgs e)
165 {
166 _state++;
167 if (_state >= NUM_STATES)
168 _state = 0;
169
170 GoToState(true);
171 }
172
173 #endregion
174
175 #region State
176
177 private void GoToState(bool useTransitions)
178 {
179 if ((bool)IsRunning)
180 {
181 VisualStateManager.GoToState(this, string.Format("state{0}", _state + 1), useTransitions);
182 }
183 else
184 {
185 VisualStateManager.GoToState(this, "normal", useTransitions);
186 }
187 }
188
189 #endregion
190
191 #region Parts
192
193 void BusyAnimation_LayoutUpdated(object sender, EventArgs e)
194 {
195 ArrangeParts();
196 }
197
198 void BusyAnimation_SizeChanged(object sender, SizeChangedEventArgs e)
199 {
200 ArrangeParts();
201 }
202
203 private void ArrangeParts()
204 {
205 double width = ActualWidth;
206 double height = ActualHeight;
207 double scale = Math.Min(ActualWidth, ActualHeight);
208 double theta = (2.0 * Math.PI) / NUM_STATES;
209
210 for (int n = 0; n < NUM_STATES; n++)
211 {
212 FrameworkElement item = (FrameworkElement)FindChild(this, "part" + (n + 1));
213 if (item != null)
214 {
215 double itemTheta = theta * (double)n;
216
217 double itemScale = scale / 4.0;
218 double radius = (scale - itemScale) / 2.0;
219
220 double x = (radius * Math.Cos(itemTheta)) - (itemScale / 2) + (ActualWidth / 2);
221 double y = (radius * Math.Sin(itemTheta)) - (itemScale / 2) + (ActualHeight / 2);
222
223 item.Width = itemScale;
224 item.Height = itemScale;
225 item.SetValue(Canvas.LeftProperty, x);
226 item.SetValue(Canvas.TopProperty, y);
227 }
228 }
229 }
230
231 #endregion
232
233 #region Helpers
234
235 private DependencyObject FindChild(DependencyObject parent, string name)
236 {
237 DependencyObject found = null;
238 int count = VisualTreeHelper.GetChildrenCount(parent);
239 for (int x = 0; x < count; x++)
240 {
241 DependencyObject child = VisualTreeHelper.GetChild(parent, x);
242 string childName = child.GetValue(FrameworkElement.NameProperty) as string;
243 if (childName == name)
244 {
245 found = child;
246 break;
247 }
248 else found = FindChild(child, name);
249 }
250
251 return found;
252 }
253
254 #endregion
255 }
256}
257#endif
bool IsRunning
Gets or sets a property controlling whether the animation is running.
static readonly DependencyProperty IsRunningProperty
IsRunning property to control whether the animation is running.
BusyAnimation()
Creates an instance of the control.
TimeSpan StepInterval
Gets or sets a property controlling the speed of the animation.
static readonly DependencyProperty StepIntervalProperty
StepInterval property to control speed of animation.