154 lines
5.4 KiB
C#
154 lines
5.4 KiB
C#
|
|
using System.Windows;
|
||
|
|
using System.Windows.Controls;
|
||
|
|
using System.Windows.Data;
|
||
|
|
using System.Windows.Input;
|
||
|
|
using TabletTester2025.Views;
|
||
|
|
|
||
|
|
namespace TabletTester2025.Helpers
|
||
|
|
{
|
||
|
|
public static class NumericInput
|
||
|
|
{
|
||
|
|
public static readonly DependencyProperty IsEnabledProperty =
|
||
|
|
DependencyProperty.RegisterAttached(
|
||
|
|
"IsEnabled",
|
||
|
|
typeof(bool),
|
||
|
|
typeof(NumericInput),
|
||
|
|
new PropertyMetadata(false, OnIsEnabledChanged));
|
||
|
|
|
||
|
|
public static readonly DependencyProperty AllowDecimalProperty =
|
||
|
|
DependencyProperty.RegisterAttached(
|
||
|
|
"AllowDecimal",
|
||
|
|
typeof(bool),
|
||
|
|
typeof(NumericInput),
|
||
|
|
new PropertyMetadata(true));
|
||
|
|
|
||
|
|
public static readonly DependencyProperty AllowNegativeProperty =
|
||
|
|
DependencyProperty.RegisterAttached(
|
||
|
|
"AllowNegative",
|
||
|
|
typeof(bool),
|
||
|
|
typeof(NumericInput),
|
||
|
|
new PropertyMetadata(false));
|
||
|
|
|
||
|
|
private static readonly DependencyProperty IsKeypadOpenProperty =
|
||
|
|
DependencyProperty.RegisterAttached(
|
||
|
|
"IsKeypadOpen",
|
||
|
|
typeof(bool),
|
||
|
|
typeof(NumericInput),
|
||
|
|
new PropertyMetadata(false));
|
||
|
|
|
||
|
|
public static readonly RoutedEvent ValueCommittedEvent =
|
||
|
|
EventManager.RegisterRoutedEvent(
|
||
|
|
"ValueCommitted",
|
||
|
|
RoutingStrategy.Bubble,
|
||
|
|
typeof(RoutedEventHandler),
|
||
|
|
typeof(NumericInput));
|
||
|
|
|
||
|
|
public static void SetIsEnabled(DependencyObject element, bool value) =>
|
||
|
|
element.SetValue(IsEnabledProperty, value);
|
||
|
|
|
||
|
|
public static bool GetIsEnabled(DependencyObject element) =>
|
||
|
|
(bool)element.GetValue(IsEnabledProperty);
|
||
|
|
|
||
|
|
public static void SetAllowDecimal(DependencyObject element, bool value) =>
|
||
|
|
element.SetValue(AllowDecimalProperty, value);
|
||
|
|
|
||
|
|
public static bool GetAllowDecimal(DependencyObject element) =>
|
||
|
|
(bool)element.GetValue(AllowDecimalProperty);
|
||
|
|
|
||
|
|
public static void SetAllowNegative(DependencyObject element, bool value) =>
|
||
|
|
element.SetValue(AllowNegativeProperty, value);
|
||
|
|
|
||
|
|
public static bool GetAllowNegative(DependencyObject element) =>
|
||
|
|
(bool)element.GetValue(AllowNegativeProperty);
|
||
|
|
|
||
|
|
public static bool GetIsKeypadOpen(DependencyObject element) =>
|
||
|
|
(bool)element.GetValue(IsKeypadOpenProperty);
|
||
|
|
|
||
|
|
public static void AddValueCommittedHandler(DependencyObject element, RoutedEventHandler handler)
|
||
|
|
{
|
||
|
|
if (element is UIElement uiElement)
|
||
|
|
uiElement.AddHandler(ValueCommittedEvent, handler);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void RemoveValueCommittedHandler(DependencyObject element, RoutedEventHandler handler)
|
||
|
|
{
|
||
|
|
if (element is UIElement uiElement)
|
||
|
|
uiElement.RemoveHandler(ValueCommittedEvent, handler);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void SetIsKeypadOpen(DependencyObject element, bool value) =>
|
||
|
|
element.SetValue(IsKeypadOpenProperty, value);
|
||
|
|
|
||
|
|
private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||
|
|
{
|
||
|
|
if (d is not TextBox textBox)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if ((bool)e.NewValue)
|
||
|
|
{
|
||
|
|
textBox.PreviewMouseLeftButtonDown += TextBox_PreviewMouseLeftButtonDown;
|
||
|
|
textBox.PreviewTouchDown += TextBox_PreviewTouchDown;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
textBox.PreviewMouseLeftButtonDown -= TextBox_PreviewMouseLeftButtonDown;
|
||
|
|
textBox.PreviewTouchDown -= TextBox_PreviewTouchDown;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||
|
|
{
|
||
|
|
if (sender is not TextBox textBox || !CanOpen(textBox))
|
||
|
|
return;
|
||
|
|
|
||
|
|
e.Handled = true;
|
||
|
|
OpenKeypad(textBox);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void TextBox_PreviewTouchDown(object sender, TouchEventArgs e)
|
||
|
|
{
|
||
|
|
if (sender is not TextBox textBox || !CanOpen(textBox))
|
||
|
|
return;
|
||
|
|
|
||
|
|
e.Handled = true;
|
||
|
|
OpenKeypad(textBox);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static bool CanOpen(TextBox textBox)
|
||
|
|
{
|
||
|
|
return GetIsEnabled(textBox)
|
||
|
|
&& !GetIsKeypadOpen(textBox)
|
||
|
|
&& !textBox.IsReadOnly
|
||
|
|
&& textBox.IsEnabled;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void OpenKeypad(TextBox textBox)
|
||
|
|
{
|
||
|
|
SetIsKeypadOpen(textBox, true);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var window = Window.GetWindow(textBox);
|
||
|
|
var keypad = new NumericKeypadWindow(
|
||
|
|
textBox.Text,
|
||
|
|
GetAllowDecimal(textBox),
|
||
|
|
GetAllowNegative(textBox))
|
||
|
|
{
|
||
|
|
Owner = window
|
||
|
|
};
|
||
|
|
|
||
|
|
if (keypad.ShowDialog() == true)
|
||
|
|
{
|
||
|
|
textBox.Text = string.IsNullOrWhiteSpace(keypad.ResultText) ? "0" : keypad.ResultText;
|
||
|
|
textBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource();
|
||
|
|
textBox.RaiseEvent(new RoutedEventArgs(ValueCommittedEvent, textBox));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
finally
|
||
|
|
{
|
||
|
|
SetIsKeypadOpen(textBox, false);
|
||
|
|
Keyboard.ClearFocus();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|