123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- using System;
- using System.Collections.Generic;
- using System.Windows.Controls;
- using System.Windows.Input;
- using Microsoft.Xaml.Behaviors;
- namespace InABox.WPF;
- public class TextBoxTimeSpanMaskBehavior : Behavior<TextBox>
- {
- private bool bFirst = true;
- private List<Tuple<int, char>> _separators = new List<Tuple<int, char>>();
-
- private string _format = "HH:mm";
- public string Format
- {
- get => _format;
- set
- {
- _format = value;
- ReloadSeparators();
- }
- }
- private void ReloadSeparators()
- {
- _separators.Clear();
- var formatted = new TimeSpanToStringConverter(_format).Convert(DateTime.Now.TimeOfDay);
- int iOffset = 0;
- for (int i=0; i<formatted.Length; i++)
- {
- var ch = formatted[i];
- if (!Char.IsNumber(ch))
- {
- _separators.Add(new Tuple<int, char>(i - iOffset, ch));
- iOffset++;
- }
- }
- }
- public TextBoxTimeSpanMaskBehavior(string? format)
- {
- Format = String.IsNullOrWhiteSpace(format)
- ? "HH:mm"
- : format;
- }
-
- protected override void OnAttached()
- {
- AssociatedObject.PreviewTextInput += PreviewTextInput;
- AssociatedObject.TextChanged += TextChanged;
- AssociatedObject.MouseDoubleClick += MouseDoubleClick;
- base.OnAttached();
- }
- protected override void OnDetaching()
- {
- AssociatedObject.MouseDoubleClick -= MouseDoubleClick;
- AssociatedObject.TextChanged -= TextChanged;
- AssociatedObject.PreviewTextInput -= PreviewTextInput;
- base.OnDetaching();
- }
- private void MouseDoubleClick(object sender, MouseButtonEventArgs e)
- {
- AssociatedObject.Text = String.Format("{0:" + Format + "}", DateTime.Now.TimeOfDay);
- }
- private void PreviewTextInput(object sender, TextCompositionEventArgs e)
- {
- bFirst = false;
- if (!int.TryParse(e.Text, out int _))
- e.Handled = true;
- }
- private void TextChanged(object sender, TextChangedEventArgs e)
- {
- var plaintext = AssociatedObject.Text?.Trim() ?? "";
- foreach (var separator in _separators)
- plaintext = plaintext.Replace(separator.Item2.ToString(), "");
-
- var decorated = plaintext;
- for (int i = _separators.Count - 1; i >= 0; i--)
- {
- if (plaintext.Length >= _separators[i].Item1)
- decorated = decorated.Insert(_separators[i].Item1, _separators[i].Item2.ToString());
- }
- AssociatedObject.Text = decorated;
- if (bFirst)
- AssociatedObject.SelectAll();
- else
- AssociatedObject.Select(AssociatedObject.Text.Length, 0);
- e.Handled = true;
- }
- }
|