这是 WPF 中处理输入限制最健壮且最推荐的方式。
我将提供一个纯整数限制的附加属性,并确保它能处理键盘输入、粘贴和所有特殊情况。
利用自定义附加属性基类DependencyProperty封装一个附加属性传给textbox这个控件使用,
实际上自定义属性是可重复使用的,界面上的textbox都可以使用这个属性进行限制只能输入正整数和正浮点数
步骤一:创建附加属性类(自定义属性)
请在您的项目(例如NX_Openg.Control命名空间下)创建一个名为TextBoxBehavior.cs的文件,并粘贴以下代码:
using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace NX_Openg.Control { /// <summary> /// 提供TextBox的附加行为,用于限制输入为纯整数。 /// </summary> public static class TextBoxBehavior { public static readonly DependencyProperty IsIntegerProperty = DependencyProperty.RegisterAttached( "IsInteger", typeof(bool), typeof(TextBoxBehavior), new PropertyMetadata(false, OnIsIntegerChanged)); public static bool GetIsInteger(DependencyObject obj) { return (bool)obj.GetValue(IsIntegerProperty); } public static void SetIsInteger(DependencyObject obj, bool value) { obj.SetValue(IsIntegerProperty, value); } private static void OnIsIntegerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is TextBox textBox) { if ((bool)e.NewValue) { // 附加事件处理器:处理字符输入 textBox.PreviewTextInput += TextBox_PreviewTextInput; // 附加事件处理器:处理特殊按键 textBox.PreviewKeyDown += TextBox_PreviewKeyDown; // 附加事件处理器:专门处理粘贴操作 DataObject.AddPastingHandler(textBox, TextBox_Pasting); } else { // 移除事件处理器 textBox.PreviewTextInput -= TextBox_PreviewTextInput; textBox.PreviewKeyDown -= TextBox_PreviewKeyDown; DataObject.RemovePastingHandler(textBox, TextBox_Pasting); } } } // 负责过滤字符输入(包括输入法和粘贴的字符) private static void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { // 检查输入是否为数字 if (!char.IsDigit(e.Text, 0)) { e.Handled = true; // 阻止非数字字符 } } // 负责处理特殊按键(如 Backspace, Delete, 方向键, 空格) private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) { // 1. 允许控制键:Back、Delete、Tab、Enter、方向键 if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Tab || e.Key == Key.Enter || (e.Key >= Key.Left && e.Key <= Key.Down)) { return; } // 2. 允许 Ctrl 组合键 (A, C, V, X) if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) { return; } // 3. 阻止空格键 if (e.Key == Key.Space) { e.Handled = true; return; } // 4. 阻止所有非数字按键(字母、符号等) // 注意:我们不在这里处理数字键,让它们继续触发 PreviewTextInput // 但如果是非数字键,且不是控制键,则直接阻止。 // 检查是否为数字键(主键盘和数字键盘) bool isDigit = (e.Key >= Key.D0 && e.Key <= Key.D9) || (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9); if (!isDigit) { e.Handled = true; } // 如果是数字键,我们让它通过,由 PreviewTextInput 再次确认 } // 专门处理粘贴操作,确保粘贴的内容是纯数字 private static void TextBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(string))) { string pasteText = (string)e.DataObject.GetData(typeof(string)); // 检查粘贴内容是否只包含数字 Regex regex = new Regex("^[0-9]+$"); if (!regex.IsMatch(pasteText)) { e.CancelCommand(); // 取消粘贴命令 } } else { e.CancelCommand(); // 取消非文本粘贴 } } } }DependencyProperty
是系统自带的自定义属性封装基类,创建这个自定义属性对象可以封装我们自己所需功能的自定义属性,属性可以被wpf大部分控件随意调用,只不过,我们这个属性类封装的代码是用来处理键盘输入的,只能适用于textbox这类的输入控件
这个类我们封装了IsPositiveFloatProperty这个自定义属性对象,ui就是通过调用这个对象来使用自定义属性
步骤二:修改 XAML (应用附加属性)
1.引用自定义属性类所在文件夹的uri
xmlns:cjp="clr-namespace:NX_Openg.Control"2.在您的TextBox上,应用新的附加属性cjp:类名.对象名="True"
<TextBox Name="text_d2" IsEnabled="{Binding ScrewInfo.Textbox2_look}" HorizontalAlignment="Left" Margin="303,67,0,0" TextWrapping="Wrap" Text="8" VerticalAlignment="Top" cjp:TextBoxBehavior.IsPositiveFloat="True" Width="120"/>