Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
TimeSpanControl.xaml.cs
3using System.Windows.Input;
4
6{
11 public partial class TimeSpanControl : UserControl
12 {
17 {
18 None,
19 EditHours,
20 EditMinutes,
21 EditSeconds,
22 EditMilliseconds
23 }
24
28 public const ushort MAX_NUMBER_MILLISECOND_DIGITS = 3;
29
30 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
36 {
37 InitializeComponent();
38 }
39
40 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41
42 private bool _digitEntry_StartWithFirstDigit = true; // If this flag is true, the next entered digit is used as 1er digit (rightmost digit)
43 private byte _digitEntry_CountEnteredZeroes = 0; // Number of entered zeroes. This is reset whenever the EditModes changes
44
45 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46
47 #region Dependency Properties
48
53 {
54 get { return (TimeSpanControlEditModes)GetValue(EditModeProperty); }
55 set { SetValue(EditModeProperty, value); }
56 }
57
61 public static readonly DependencyProperty EditModeProperty = DependencyProperty.Register(nameof(EditMode), typeof(TimeSpanControlEditModes), typeof(TimeSpanControl), new UIPropertyMetadata(TimeSpanControlEditModes.EditMinutes, new PropertyChangedCallback(OnEditModeChanged)));
62
63 private static void OnEditModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
64 {
65 TimeSpanControl control = obj as TimeSpanControl;
66 control._digitEntry_StartWithFirstDigit = true;
67 control._digitEntry_CountEnteredZeroes = 0;
68 }
69
70 // ----------------------------------------------------------------------------------------------------------------------------------------------
71
75 public TimeSpan Value
76 {
77 get { return (TimeSpan)GetValue(ValueProperty); }
78 set { SetValue(ValueProperty, value); }
79 }
80
84 public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(TimeSpan), typeof(TimeSpanControl), new FrameworkPropertyMetadata(TimeSpan.Zero, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnValueChanged)));
85
86 private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
87 {
88 TimeSpanControl control = obj as TimeSpanControl;
89 control.Hours = ((TimeSpan)e.NewValue).Hours;
90 control.Minutes = ((TimeSpan)e.NewValue).Minutes;
91 control.Seconds = ((TimeSpan)e.NewValue).Seconds;
92 control.Milliseconds = ((TimeSpan)e.NewValue).Milliseconds;
93 }
94
95 // ----------------------------------------------------------------------------------------------------------------------------------------------
96
100 public int Hours
101 {
102 get { return (int)GetValue(HoursProperty); }
103 set { SetValue(HoursProperty, value); }
104 }
105
109 public static readonly DependencyProperty HoursProperty = DependencyProperty.Register(nameof(Hours), typeof(int), typeof(TimeSpanControl), new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
110
114 public int Minutes
115 {
116 get { return (int)GetValue(MinutesProperty); }
117 set { SetValue(MinutesProperty, value); }
118 }
119
123 public static readonly DependencyProperty MinutesProperty = DependencyProperty.Register(nameof(Minutes), typeof(int), typeof(TimeSpanControl), new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
124
128 public int Seconds
129 {
130 get { return (int)GetValue(SecondsProperty); }
131 set { SetValue(SecondsProperty, value); }
132 }
133
137 public static readonly DependencyProperty SecondsProperty = DependencyProperty.Register(nameof(Seconds), typeof(int), typeof(TimeSpanControl), new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
138
142 public int Milliseconds
143 {
144 get { return (int)GetValue(MillisecondsProperty); }
145 set { SetValue(MillisecondsProperty, value); }
146 }
147
151 public static readonly DependencyProperty MillisecondsProperty = DependencyProperty.Register(nameof(Milliseconds), typeof(int), typeof(TimeSpanControl), new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
152
153 private static void OnTimeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
154 {
155 if (obj is TimeSpanControl control)
156 {
157 control.Value = new TimeSpan(0, control.Hours, control.Minutes, control.Seconds, control.Milliseconds);
158 control.updateMillisecondsDisplayed();
159 }
160 }
161
162 // ----------------------------------------------------------------------------------------------------------------------------------------------
163
167 public ushort MillisecondDigits
168 {
169 get => (ushort)GetValue(MillisecondDigitsProperty);
170 set => SetValue(MillisecondDigitsProperty, value);
171 }
172
176 public static readonly DependencyProperty MillisecondDigitsProperty = DependencyProperty.Register(nameof(MillisecondDigits), typeof(ushort), typeof(TimeSpanControl), new PropertyMetadata(MAX_NUMBER_MILLISECOND_DIGITS, OnMillisecondDigitsChanged));
177
178 private static void OnMillisecondDigitsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
179 {
180 if (d is TimeSpanControl control)
181 {
182 if(control.MillisecondDigits < 1) { control.MillisecondDigits = 1; }
183 if (control.MillisecondDigits > MAX_NUMBER_MILLISECOND_DIGITS) { control.MillisecondDigits = MAX_NUMBER_MILLISECOND_DIGITS; }
184 control.updateMillisecondsDisplayed();
185 }
186 }
187
192 {
193 get { return (string)GetValue(MillisecondsDisplayedProperty); }
194 private set { SetValue(MillisecondsDisplayedProperty, value); }
195 }
196
197 private static readonly DependencyPropertyKey MillisecondsDisplayedPropertyKey = DependencyProperty.RegisterReadOnly(nameof(MillisecondsDisplayed), typeof(string), typeof(TimeSpanControl), new PropertyMetadata("000"));
198
202 public static readonly DependencyProperty MillisecondsDisplayedProperty = MillisecondsDisplayedPropertyKey.DependencyProperty;
203
204 private void updateMillisecondsDisplayed()
205 {
206 int factor = (int)Math.Pow(10, MAX_NUMBER_MILLISECOND_DIGITS - MillisecondDigits);
207 int displayedMilliseconds = Milliseconds / factor;
208 string format = new string('0', Math.Max((ushort)1, MillisecondDigits));
209 string formattedMilliseconds = displayedMilliseconds.ToString(format);
210 SetValue(MillisecondsDisplayedPropertyKey, formattedMilliseconds);
211 }
212
213 // ----------------------------------------------------------------------------------------------------------------------------------------------
214
218 public bool HoursVisible
219 {
220 get { return (bool)GetValue(HoursVisibleProperty); }
221 set { SetValue(HoursVisibleProperty, value); }
222 }
223
227 public static readonly DependencyProperty HoursVisibleProperty = DependencyProperty.Register(nameof(HoursVisible), typeof(bool), typeof(TimeSpanControl), new UIPropertyMetadata(true, new PropertyChangedCallback(OnVisiblePartsChanged)));
228
233 {
234 get { return (bool)GetValue(MillisecondsVisibleProperty); }
235 set { SetValue(MillisecondsVisibleProperty, value); }
236 }
237
241 public static readonly DependencyProperty MillisecondsVisibleProperty = DependencyProperty.Register(nameof(MillisecondsVisible), typeof(bool), typeof(TimeSpanControl), new UIPropertyMetadata(true, new PropertyChangedCallback(OnVisiblePartsChanged)));
242
243 private static void OnVisiblePartsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
244 {
245 TimeSpanControl control = obj as TimeSpanControl;
246 if(!control.HoursVisible && control.EditMode == TimeSpanControlEditModes.EditHours)
247 {
248 control.EditMode = TimeSpanControlEditModes.EditMinutes;
249 }
250 else if (!control.MillisecondsVisible && control.EditMode == TimeSpanControlEditModes.EditMilliseconds)
251 {
252 control.EditMode = TimeSpanControlEditModes.EditSeconds;
253 }
254 }
255
256 #endregion
257
258 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
259
260 #region Digit Update Logic
261
270 private void handleDigitInput(byte digit)
271 {
272 if(digit > 9) { digit = 9; }
273
274 int oldValueMultiplier = _digitEntry_StartWithFirstDigit ? 0 : 10;
275 _digitEntry_StartWithFirstDigit = false;
276 if(digit == 0) { _digitEntry_CountEnteredZeroes++; }
277 switch (EditMode)
278 {
279 case TimeSpanControlEditModes.EditHours:
280 Hours = (Hours * oldValueMultiplier) + digit;
281 if (Hours > 2 || _digitEntry_CountEnteredZeroes >= (digit == 0 ? 2 : 1)) { EditMode = TimeSpanControlEditModes.EditMinutes; }
282 break;
283 case TimeSpanControlEditModes.EditMinutes:
284 Minutes = (Minutes * oldValueMultiplier) + digit;
285 if (Minutes >= 6 || _digitEntry_CountEnteredZeroes >= (digit == 0 ? 2 : 1)) { EditMode = TimeSpanControlEditModes.EditSeconds; }
286 break;
287 case TimeSpanControlEditModes.EditSeconds:
288 Seconds = (Seconds * oldValueMultiplier) + digit;
290 {
291 if (Seconds >= 6 || _digitEntry_CountEnteredZeroes >= (digit == 0 ? 2 : 1)) { EditMode = TimeSpanControlEditModes.EditMilliseconds; }
292 }
293 else
294 {
295 if (Seconds * 10 >= 59 || _digitEntry_CountEnteredZeroes >= 2) { _digitEntry_StartWithFirstDigit = true; _digitEntry_CountEnteredZeroes = 0; }
296 }
297 break;
298 case TimeSpanControlEditModes.EditMilliseconds:
299 int factor = (int)Math.Pow(10, MAX_NUMBER_MILLISECOND_DIGITS - MillisecondDigits); // 1, 10, 100
300 int maxValue = 1000 - factor; // 900, 990, 999
301
302 int tmpMilliseconds = (((Milliseconds / factor) * oldValueMultiplier) + digit) * factor;
303 Milliseconds = Math.Min(maxValue, tmpMilliseconds);
304
305 if (Milliseconds >= maxValue || Milliseconds * 10 >= maxValue || _digitEntry_CountEnteredZeroes >= MAX_NUMBER_MILLISECOND_DIGITS)
306 {
307 _digitEntry_StartWithFirstDigit = true;
308 _digitEntry_CountEnteredZeroes = 0;
309 }
310 break;
311 }
312 }
313
317 private void increaseDigit()
318 {
319 switch (EditMode)
320 {
321 case TimeSpanControlEditModes.EditHours:
322 if(Hours < 23) { Hours++; }
323 break;
324 case TimeSpanControlEditModes.EditMinutes:
325 if(Minutes < 59) { Minutes++; }
326 break;
327 case TimeSpanControlEditModes.EditSeconds:
328 if(Seconds < 59) { Seconds++; }
329 break;
330 case TimeSpanControlEditModes.EditMilliseconds:
331 int step = (int)Math.Pow(10, MAX_NUMBER_MILLISECOND_DIGITS - MillisecondDigits);
332 int max = 1000 - step; // e.g. 900, 990 oder 999
333 if (Milliseconds + step <= max)
334 {
335 Milliseconds += step;
336 }
337 else
338 {
339 Milliseconds = max;
340 }
341 break;
342 }
343 }
344
348 private void decreaseDigit()
349 {
350 switch (EditMode)
351 {
352 case TimeSpanControlEditModes.EditHours:
353 if (Hours > 0) { Hours--; }
354 break;
355 case TimeSpanControlEditModes.EditMinutes:
356 if (Minutes > 0) { Minutes--; }
357 break;
358 case TimeSpanControlEditModes.EditSeconds:
359 if (Seconds > 0) { Seconds--; }
360 break;
361 case TimeSpanControlEditModes.EditMilliseconds:
362 int step = (int)Math.Pow(10, MAX_NUMBER_MILLISECOND_DIGITS - MillisecondDigits);
363 if (Milliseconds - step >= 0)
364 {
365 Milliseconds -= step;
366 }
367 else
368 {
369 Milliseconds = 0;
370 }
371 break;
372 }
373 }
374
375 #endregion
376
377 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
378
379 #region Control Events
380
381 private void txt_hours_PreviewMouseDown(object sender, MouseButtonEventArgs e)
382 {
383 this.Focus();
385 e.Handled = true; // avoids focus loss by e.g. parent ListViewItem
386 }
387
388 private void txt_minutes_PreviewMouseDown(object sender, MouseButtonEventArgs e)
389 {
390 this.Focus();
392 e.Handled = true; // avoids focus loss by e.g. parent ListViewItem
393 }
394
395 private void txt_seconds_PreviewMouseDown(object sender, MouseButtonEventArgs e)
396 {
397 this.Focus();
399 e.Handled = true; // avoids focus loss by e.g. parent ListViewItem
400 }
401
402 private void txt_milliseconds_PreviewMouseDown(object sender, MouseButtonEventArgs e)
403 {
404 this.Focus();
405 EditMode = TimeSpanControlEditModes.EditMilliseconds;
406 e.Handled = true; // avoids focus loss by e.g. parent ListViewItem
407 }
408
409 private void UserControl_PreviewKeyDown(object sender, KeyEventArgs e)
410 {
411 if (e.Key == Key.Tab)
412 {
413 // Return here to enable the default behavior of the Tab key
414 return;
415 }
416 else if ((e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9))
417 {
418 string keyString = e.Key.ToString().Replace("NumPad", "").Replace("D", "");
419 byte digit;
420 if (byte.TryParse(keyString, out digit))
421 {
422 handleDigitInput(digit);
423 }
424 }
425 else if (e.Key == Key.Right)
426 {
427 TimeSpanControlEditModes highestMode = TimeSpanControlEditModes.EditMilliseconds;
428 if(!MillisecondsVisible) { highestMode = TimeSpanControlEditModes.EditSeconds; }
429 if (EditMode < highestMode)
430 {
431 EditMode++;
432 }
433 }
434 else if (e.Key == Key.Left)
435 {
437 if (!HoursVisible) { lowestMode = TimeSpanControlEditModes.EditMinutes; }
438 if (EditMode > lowestMode)
439 {
440 EditMode--;
441 }
442 }
443 else if(e.Key == Key.Up)
444 {
446 }
447 else if (e.Key == Key.Down)
448 {
450 }
451 else if (e.Key == Key.Enter)
452 {
454 Keyboard.ClearFocus();
455 }
456 e.Handled = true;
457 }
458
459 private void btn_Increase_Click(object sender, RoutedEventArgs e)
460 {
462 }
463
464 private void btn_Decrease_Click(object sender, RoutedEventArgs e)
465 {
467 }
468
469 #endregion
470 }
471}
Interaktionslogik für TimeSpanControl.xaml This control is inspired by the HTML time input (https://w...
string MillisecondsDisplayed
Read-only property that contains the formatted milliseconds depending on the MillisecondDigits proper...
static readonly DependencyProperty MillisecondsVisibleProperty
Dependency property for the MillisecondsVisible property.
void handleDigitInput(byte digit)
Integrate the entered digit into the TimeSpan value.
static readonly DependencyProperty ValueProperty
Dependency property for the Value property.
int Seconds
Seconds of the Value (TimeSpan.Seconds)
TimeSpan Value
TimeSpan value that is editable by this control
bool HoursVisible
If true, the controls show the Hours field.
static readonly DependencyProperty EditModeProperty
Dependency property for the EditMode property.
static readonly DependencyProperty MillisecondDigitsProperty
Dependency property for the MillisecondDigits property.
TimeSpanControlEditModes
Enum with editable parts of the TimeSpan.
bool MillisecondsVisible
If true, the controls show the Milliseconds field.
TimeSpanControl()
Constructor of the TimeSpanControl.
int Milliseconds
Milliseconds of the Value (TimeSpan.Milliseconds)
static readonly DependencyProperty HoursProperty
Dependency property for the Hours property.
void increaseDigit()
Increase the digits depending on the current EditMode
static readonly DependencyProperty HoursVisibleProperty
Dependency property for the HoursVisible property.
static readonly DependencyProperty MillisecondsDisplayedProperty
Read-only dependency property for the MillisecondsDisplayed property.
static readonly DependencyProperty SecondsProperty
Dependency property for the Seconds property.
static readonly DependencyProperty MillisecondsProperty
Dependency property for the Milliseconds property.
static readonly DependencyProperty MinutesProperty
Dependency property for the Minutes property.
int Hours
Hours of the Value (TimeSpan.Hours)
int Minutes
Minutes of the Value (TimeSpan.Minutes)
ushort MillisecondDigits
Number of digits to display for the milliseconds.
const ushort MAX_NUMBER_MILLISECOND_DIGITS
Maximum number of digits for the milliseconds.
void decreaseDigit()
Decrease the digits depending on the current EditMode
TimeSpanControlEditModes EditMode
Current edit mode.