Files
CSI-Z420-Tablet-Multi-Funct…/Helpers/NumericInput.cs
2026-05-18 14:06:04 +08:00

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();
}
}
}
}