107 lines
4.0 KiB
C#
107 lines
4.0 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Controls.Primitives;
|
|
using System.Windows.Input;
|
|
|
|
namespace Elwig.Controls {
|
|
public class IntegerUpDown : TextBox {
|
|
|
|
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register(nameof(Minimum), typeof(int?), typeof(IntegerUpDown), new FrameworkPropertyMetadata(null));
|
|
public int? Minimum {
|
|
get => (int?)GetValue(MinimumProperty);
|
|
set => SetValue(MinimumProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(nameof(Maximum), typeof(int?), typeof(IntegerUpDown), new FrameworkPropertyMetadata(null));
|
|
public int? Maximum {
|
|
get => (int?)GetValue(MaximumProperty);
|
|
set => SetValue(MaximumProperty, value);
|
|
}
|
|
|
|
public int? Value {
|
|
get => int.TryParse(Text, out var res) ? res : null;
|
|
set => Text = $"{value}";
|
|
}
|
|
|
|
static IntegerUpDown() {
|
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(typeof(IntegerUpDown)));
|
|
}
|
|
|
|
public IntegerUpDown() {
|
|
TextChanged += IntegerUpDown_TextChanged;
|
|
LostFocus += IntegerUpDown_LostFocus;
|
|
KeyUp += IntegerUpDown_KeyUp;
|
|
}
|
|
|
|
public override void OnApplyTemplate() {
|
|
var incButton = GetTemplateChild("IncrementButton") as RepeatButton;
|
|
var decButton = GetTemplateChild("DecrementButton") as RepeatButton;
|
|
incButton!.Click += IncrementButton_Click;
|
|
decButton!.Click += DecrementButton_Click;
|
|
base.OnApplyTemplate();
|
|
}
|
|
|
|
private void IntegerUpDown_TextChanged(object sender, TextChangedEventArgs evt) {
|
|
var idx = CaretIndex;
|
|
Text = new string(Text.Where(char.IsAsciiDigit).Take(4).ToArray());
|
|
CaretIndex = idx;
|
|
evt.Handled = !(Value >= Minimum && Value <= Maximum);
|
|
if (idx >= 4) {
|
|
if (Value < Minimum) {
|
|
Value = Minimum;
|
|
} else if (Value > Maximum) {
|
|
Value = Maximum;
|
|
}
|
|
CaretIndex = 4;
|
|
}
|
|
}
|
|
|
|
private void IntegerUpDown_LostFocus(object sender, RoutedEventArgs evt) {
|
|
if (Value < Minimum) {
|
|
Value = Minimum;
|
|
} else if (Value > Maximum) {
|
|
Value = Maximum;
|
|
}
|
|
}
|
|
|
|
private void IncrementButton_Click(object sender, RoutedEventArgs evt) {
|
|
Value = Math.Min((Value ?? 0) + 1, Maximum ?? int.MaxValue);
|
|
}
|
|
|
|
private void DecrementButton_Click(object sender, RoutedEventArgs evt) {
|
|
Value = Math.Max((Value ?? 0) - 1, Minimum ?? int.MinValue);
|
|
}
|
|
|
|
private void IntegerUpDown_KeyUp(object sender, KeyEventArgs evt) {
|
|
switch (evt.Key) {
|
|
case Key.Up:
|
|
case Key.Add:
|
|
case Key.OemPlus:
|
|
Value = Math.Min((Value ?? 0) + 1, Maximum ?? int.MaxValue);
|
|
evt.Handled = true;
|
|
CaretIndex = 4;
|
|
break;
|
|
case Key.Down:
|
|
case Key.Subtract:
|
|
case Key.OemMinus:
|
|
Value = Math.Max((Value ?? 0) - 1, Minimum ?? int.MinValue);
|
|
evt.Handled = true;
|
|
CaretIndex = 4;
|
|
break;
|
|
case Key.PageUp:
|
|
Value = Math.Min((Value ?? 0) + 10, Maximum ?? int.MaxValue);
|
|
evt.Handled = true;
|
|
CaretIndex = 4;
|
|
break;
|
|
case Key.PageDown:
|
|
Value = Math.Max((Value ?? 0) - 10, Minimum ?? int.MinValue);
|
|
evt.Handled = true;
|
|
CaretIndex = 4;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|