NumericInput.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Maywork.WPF.Helpers;
public static class NumericInput
{
public static readonly DependencyProperty AllowDecimalProperty =
DependencyProperty.RegisterAttached(
"AllowDecimal",
typeof(bool),
typeof(NumericInput),
new PropertyMetadata(false, OnChanged));
public static readonly DependencyProperty AllowNegativeProperty =
DependencyProperty.RegisterAttached(
"AllowNegative",
typeof(bool),
typeof(NumericInput),
new PropertyMetadata(false, OnChanged));
public static void SetAllowDecimal(DependencyObject obj, bool value)
=> obj.SetValue(AllowDecimalProperty, value);
public static bool GetAllowDecimal(DependencyObject obj)
=> (bool)obj.GetValue(AllowDecimalProperty);
public static void SetAllowNegative(DependencyObject obj, bool value)
=> obj.SetValue(AllowNegativeProperty, value);
public static bool GetAllowNegative(DependencyObject obj)
=> (bool)obj.GetValue(AllowNegativeProperty);
static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not TextBox tb) return;
tb.PreviewTextInput -= OnPreviewTextInput;
tb.PreviewTextInput += OnPreviewTextInput;
DataObject.RemovePastingHandler(tb, OnPaste);
DataObject.AddPastingHandler(tb, OnPaste);
}
static void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (sender is not TextBox tb) return;
bool allowDecimal = GetAllowDecimal(tb);
bool allowNegative = GetAllowNegative(tb);
string text = e.Text;
if (char.IsDigit(text, 0))
return;
if (text == "." && allowDecimal && !tb.Text.Contains("."))
return;
if (text == "-" && allowNegative && tb.SelectionStart == 0 && !tb.Text.Contains("-"))
return;
e.Handled = true;
}
static void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if (sender is not TextBox tb) return;
if (!e.DataObject.GetDataPresent(typeof(string)))
{
e.CancelCommand();
return;
}
string text = (string)e.DataObject.GetData(typeof(string));
bool allowDecimal = GetAllowDecimal(tb);
bool allowNegative = GetAllowNegative(tb);
string pattern =
allowDecimal
? (allowNegative ? @"^-?\d*(\.\d*)?$" : @"^\d*(\.\d*)?$")
: (allowNegative ? @"^-?\d*$" : @"^\d*$");
if (!System.Text.RegularExpressions.Regex.IsMatch(text, pattern))
e.CancelCommand();
}
}
/*
# 使い方
xmlns:h="clr-namespace:Maywork.WPF.Helpers"
XAML 整数
<TextBox
TextAlignment="Right"
h:NumericInput.AllowNegative="True"
Height="32" Width="100" />
XAML 小数
<TextBox h:NumericInput.AllowDecimal="True"
h:NumericInput.AllowNegative="True"/>
*/
Download

コメント