1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-10-16 06:00:45 +00:00
msfs-popout-panel-manager/MainApp/CustomControl/NumericUpDown.cs
2024-02-27 21:44:21 -05:00

222 lines
8.1 KiB
C#

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace MSFSPopoutPanelManager.MainApp.CustomControl
{
[TemplatePart(Name = "PART_TextBox", Type = typeof(TextBox))]
[TemplatePart(Name = "PART_ButtonUp", Type = typeof(ButtonBase))]
[TemplatePart(Name = "PART_ButtonDown", Type = typeof(ButtonBase))]
public class NumericUpDown : Control
{
private TextBox PART_TextBox = new TextBox();
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
TextBox textBox = GetTemplateChild("PART_TextBox") as TextBox;
if (textBox != null)
{
PART_TextBox = textBox;
PART_TextBox.PreviewKeyDown += textBox_PreviewKeyDown;
PART_TextBox.TextChanged += textBox_TextChanged;
PART_TextBox.Text = Value.ToString();
}
ButtonBase PART_ButtonUp = GetTemplateChild("PART_ButtonUp") as ButtonBase;
if (PART_ButtonUp != null)
{
PART_ButtonUp.Click += buttonUp_Click;
}
ButtonBase PART_ButtonDown = GetTemplateChild("PART_ButtonDown") as ButtonBase;
if (PART_ButtonDown != null)
{
PART_ButtonDown.Click += buttonDown_Click;
}
}
static NumericUpDown()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown), new FrameworkPropertyMetadata(typeof(NumericUpDown)));
}
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent(
"ValueChanged", RoutingStrategy.Direct,
typeof(ValueChangedEventHandler), typeof(NumericUpDown));
public event ValueChangedEventHandler ValueChanged
{
add
{
base.AddHandler(NumericUpDown.ValueChangedEvent, value);
}
remove
{
base.RemoveHandler(NumericUpDown.ValueChangedEvent, value);
}
}
public int Places
{
get => (int)GetValue(PlacesProperty);
set => SetValue(PlacesProperty, value);
}
public static readonly DependencyProperty PlacesProperty = DependencyProperty.Register("Places", typeof(int), typeof(NumericUpDown));
public double MaxValue
{
get => (double)GetValue(MaxValueProperty);
set => SetValue(MaxValueProperty, value);
}
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(100D, maxValueChangedCallback, coerceMaxValueCallback));
private static object coerceMaxValueCallback(DependencyObject d, object value)
{
double minValue = ((NumericUpDown)d).MinValue;
if ((double)value < minValue)
return minValue;
return value;
}
private static void maxValueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NumericUpDown numericUpDown = ((NumericUpDown)d);
numericUpDown.CoerceValue(MinValueProperty);
numericUpDown.CoerceValue(ValueProperty);
}
public double MinValue
{
get => (double)GetValue(MinValueProperty);
set => SetValue(MinValueProperty, value);
}
public static readonly DependencyProperty MinValueProperty =
DependencyProperty.Register("MinValue", typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(0D, minValueChangedCallback, coerceMinValueCallback));
private static object coerceMinValueCallback(DependencyObject d, object value)
{
double maxValue = ((NumericUpDown)d).MaxValue;
if ((double)value > maxValue)
return maxValue;
return value;
}
private static void minValueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NumericUpDown numericUpDown = ((NumericUpDown)d);
numericUpDown.CoerceValue(NumericUpDown.MaxValueProperty);
numericUpDown.CoerceValue(NumericUpDown.ValueProperty);
}
public double Increment
{
get => (double)GetValue(IncrementProperty);
set => SetValue(IncrementProperty, value);
}
public static readonly DependencyProperty IncrementProperty =
DependencyProperty.Register(nameof(Increment), typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(1D, null, coerceIncrementCallback));
private static object coerceIncrementCallback(DependencyObject d, object value)
{
NumericUpDown numericUpDown = ((NumericUpDown)d);
double i = numericUpDown.MaxValue - numericUpDown.MinValue;
if ((double)value > i)
return i;
return value;
}
public double Value
{
get => (double)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(nameof(Value), typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(0D, valueChangedCallback, coerceValueCallback), validateValueCallback);
private static void valueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NumericUpDown numericUpDown = (NumericUpDown)d;
ValueChangedEventArgs ea =
new ValueChangedEventArgs(NumericUpDown.ValueChangedEvent, d, (double)e.OldValue, (double)e.NewValue);
numericUpDown.RaiseEvent(ea);
numericUpDown.PART_TextBox.Text = e.NewValue.ToString();
}
private static bool validateValueCallback(object value)
{
double val = (double)value;
if (val > double.MinValue && val < double.MaxValue)
return true;
else
return false;
}
private static object coerceValueCallback(DependencyObject d, object value)
{
double val = (double)value;
double minValue = ((NumericUpDown)d).MinValue;
double maxValue = ((NumericUpDown)d).MaxValue;
double result;
if (val < minValue)
result = minValue;
else if (val > maxValue)
result = maxValue;
else
result = (double)value;
return result;
}
private void buttonUp_Click(object sender, RoutedEventArgs e)
{
if (Value < MaxValue)
Value += Increment;
Value = Math.Round(Value, Places);
}
private void buttonDown_Click(object sender, RoutedEventArgs e)
{
if (Value > MinValue)
Value -= Increment;
Value = Math.Round(Value, Places);
}
private void textBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
e.Handled = true;
}
private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
int index = PART_TextBox.CaretIndex;
double result;
if (!double.TryParse(PART_TextBox.Text, out result))
{
var changes = e.Changes.FirstOrDefault();
if (changes != null)
{
PART_TextBox.Text = PART_TextBox.Text.Remove(changes.Offset, changes.AddedLength);
PART_TextBox.CaretIndex = index > 0 ? index - changes.AddedLength : 0;
}
}
else if (result < MaxValue && result > MinValue)
Value = result;
else
{
PART_TextBox.Text = Value.ToString();
PART_TextBox.CaretIndex = index > 0 ? index - 1 : 0;
}
}
}
}