wpf 只能输入int类型的文本框

WPF限制文本框只能输入整数

我做的这个文本框,可设置最大值,最小值,有失去焦点事件的话,失去焦点文本框里的数字是你上次填的数字,避免数据为空的情况。

有失去焦点事件

using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;

namespace 项目名
{
    public class IntegerTextBox : TextBox
    {
        public bool isMouseEntered = false;

        public string PreviousText
        {
            get { return (string)GetValue(PreviousTextProperty); }
            set { SetValue(PreviousTextProperty, value); }
        }
        public static readonly DependencyProperty PreviousTextProperty =
            DependencyProperty.Register("PreviousText", typeof(string), typeof(IntegerTextBox), new PropertyMetadata(string.Empty));

        public string HistoryText
        {
            get { return (string)GetValue(HistoryTextProperty); }
            set { SetValue(HistoryTextProperty, value); }
        }
        public static readonly DependencyProperty HistoryTextProperty = DependencyProperty.Register("HistoryText", typeof(string), typeof(IntegerTextBox), new PropertyMetadata(string.Empty));

        public int? MinValue
        {
            get { return (int?)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }

        public static readonly DependencyProperty MinValueProperty =
            DependencyProperty.Register("MinValue", typeof(int?), typeof(IntegerTextBox));

        public int MaxValue
        {
            get { return (int)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }

        public static readonly DependencyProperty MaxValueProperty =
        DependencyProperty.Register("MaxValue", typeof(int), typeof(IntegerTextBox), new PropertyMetadata(int.MaxValue));

        public static bool GetIsEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsGotFocusProperty);
        }

        public static void SetIsEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsGotFocusProperty, value);
        }

        public bool IsNeedLoseFucos
        {
            get { return (bool)GetValue(IsNeedLoseFucosvProperty); }
            set { SetValue(IsNeedLoseFucosvProperty, value); }
        }
        public static readonly DependencyProperty IsNeedLoseFucosvProperty =
            DependencyProperty.RegisterAttached("IsNeedLoseFucos", typeof(bool), typeof(IntegerTextBox), new PropertyMetadata(true));

        public bool IsGotFocus
        {
            get { return (bool)GetValue(IsGotFocusProperty); }
            set { SetValue(IsGotFocusProperty, value); }
        }
        public static readonly DependencyProperty IsGotFocusProperty =
            DependencyProperty.RegisterAttached("IsGotFocus", typeof(bool), typeof(IntegerTextBox), new PropertyMetadata(false));

        static IntegerTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(IntegerTextBox), new FrameworkPropertyMetadata(typeof(IntegerTextBox)));
        }

        public IntegerTextBox()
        {
            LostFocus += IntegerTextBox_LostFocus;
            PreviewTextInput += IntegerTextBox_PreviewTextInput;
        }

        private void IntegerTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Text = Text.Trim();
            string txt = Text + e.Text;
            if (txt.Length > 1 && txt.StartsWith('0'))
            {
                Text = Text.Substring(1);
            }
            if (!int.TryParse(txt, out int value))
            {
                if (!string.IsNullOrWhiteSpace(Text))
                {
                    var index = Text.IndexOf(e.Text);
                    if (index > -1) { Text = Text.Remove(index); }

                    SelectionStart = Text.Length + e.Text.Length;
                }
                e.Handled = true; // 阻止输入非数字字符
            }
            //else if (value < MinValue && value.ToString().Length == MinValue.ToString().Length)
            //{
            //    Text = MinValue.ToString(); // 将文本框的值设置为最小值
            //    SelectionStart = Text.Length + e.Text.Length;
            //    e.Handled = true; // 阻止输入超出取值范围的数字
            //}
            else if (value > MaxValue)
            {
                Text = MaxValue.ToString(); // 将文本框的值设置为最大值
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true; // 阻止输入超出取值范围的数字
            }
            else
            {
                Text = value.ToString();
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true;
            }
            SelectionStart = Text.Length + e.Text.Length;
            HistoryText = Text;
        }

        private void IntegerTextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            IsGotFocus = false;

            Text = Text.Trim();
            if (string.IsNullOrEmpty(Text))
            {
                if (!string.IsNullOrEmpty(HistoryText) && int.TryParse(HistoryText, out int history) && history > MinValue)
                {
                    Text = HistoryText;
                }
                else if (!string.IsNullOrEmpty(PreviousText))
                {
                    Text = PreviousText;
                }
                else if (MinValue is not null)
                {
                    Text = MinValue.Value.ToString();
                }
            }
            else
            {
                if (int.TryParse(Text, out int num))
                {
                    if (num < MinValue)
                    {
                        if (!string.IsNullOrEmpty(HistoryText) && int.TryParse(HistoryText, out int history) && history > MinValue)
                        {
                            Text = HistoryText;
                        }
                        else
                        {
                            Text = MinValue.ToString();
                        }
                    }
                    else if (num > MaxValue)
                    {
                        if (!string.IsNullOrEmpty(HistoryText) && int.TryParse(HistoryText, out int history) && history < MaxValue)
                        {
                            Text = HistoryText;
                        }
                        else if (!string.IsNullOrEmpty(PreviousText))
                        {
                            Text = PreviousText;
                        }
                        else
                        {
                            Text = MaxValue.ToString();
                        }
                    }
                }
            }
            SelectionStart = Text.Length;
        }
    }
}


  没有失去焦点事件:

public class IntegerTextBoxNoLF : TextBox
    {
        public bool isMouseEntered = false;

        public string PreviousText
        {
            get { return (string)GetValue(PreviousTextProperty); }
            set { SetValue(PreviousTextProperty, value); }
        }
        public static readonly DependencyProperty PreviousTextProperty =
            DependencyProperty.Register("PreviousText", typeof(string), typeof(IntegerTextBoxNoLF), new PropertyMetadata(string.Empty));

        public string HistoryText
        {
            get { return (string)GetValue(HistoryTextProperty); }
            set { SetValue(HistoryTextProperty, value); }
        }
        public static readonly DependencyProperty HistoryTextProperty = DependencyProperty.Register("HistoryText", typeof(string), typeof(IntegerTextBoxNoLF), new PropertyMetadata(string.Empty));

        public int? MinValue
        {
            get { return (int?)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }

        public static readonly DependencyProperty MinValueProperty =
            DependencyProperty.Register("MinValue", typeof(int?), typeof(IntegerTextBoxNoLF));

        public int MaxValue
        {
            get { return (int)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }

        public static readonly DependencyProperty MaxValueProperty =
        DependencyProperty.Register("MaxValue", typeof(int), typeof(IntegerTextBoxNoLF), new PropertyMetadata(int.MaxValue));

        public static bool GetIsEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsGotFocusProperty);
        }

        public static void SetIsEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsGotFocusProperty, value);
        }

        public bool IsNeedLoseFucos
        {
            get { return (bool)GetValue(IsNeedLoseFucosvProperty); }
            set { SetValue(IsNeedLoseFucosvProperty, value); }
        }
        public static readonly DependencyProperty IsNeedLoseFucosvProperty =
            DependencyProperty.RegisterAttached("IsNeedLoseFucos", typeof(bool), typeof(IntegerTextBoxNoLF), new PropertyMetadata(true));

        public bool IsGotFocus
        {
            get { return (bool)GetValue(IsGotFocusProperty); }
            set { SetValue(IsGotFocusProperty, value); }
        }
        public static readonly DependencyProperty IsGotFocusProperty =
            DependencyProperty.RegisterAttached("IsGotFocus", typeof(bool), typeof(IntegerTextBoxNoLF), new PropertyMetadata(false));


        static IntegerTextBoxNoLF()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(IntegerTextBoxNoLF), new FrameworkPropertyMetadata(typeof(IntegerTextBoxNoLF)));
        }

        public IntegerTextBoxNoLF()
        {
            PreviewTextInput += IntegerTextBox_PreviewTextInput;
            //PreviewMouseLeftButtonDown += IntegerTextBox_PreviewMouseLeftButtonDown;
        }

        private void IntegerTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Text = Text.Trim();
            string txt = Text + e.Text;
            if (txt.Length > 1 && txt.StartsWith('0'))
            {
                Text = Text.Substring(1);
            }
            if (!int.TryParse(txt, out int value))
            {
                if (!string.IsNullOrWhiteSpace(Text))
                {
                    var index = Text.IndexOf(e.Text);
                    if (index > -1) { Text = Text.Remove(index); }

                    SelectionStart = Text.Length + e.Text.Length;
                }
                e.Handled = true; // 阻止输入非数字字符
            }
            else if (value < MinValue && value.ToString().Length == MinValue.ToString().Length)
            {
                Text = MinValue.ToString(); // 将文本框的值设置为最小值
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true; // 阻止输入超出取值范围的数字
            }
            else if (value > MaxValue)
            {
                Text = MaxValue.ToString(); // 将文本框的值设置为最大值
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true; // 阻止输入超出取值范围的数字
            }
            else
            {
                Text = value.ToString();
                SelectionStart = Text.Length + e.Text.Length;
                e.Handled = true;
            }
            SelectionStart = Text.Length + e.Text.Length;
            HistoryText = Text;
        }

        private void IntegerTextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Text = string.Empty;
            Focusable = true;
            Focus();
            IsGotFocus = true;
        }
    }

调用:

 

<local:IntegerTextBox MinValue="0" MaxValue="59" TextAlignment="Center" Width="120" Height="48" Text="{Binding Program.VibrationHour,TargetNullValue={x:Static sys:String.Empty}}" VerticalContentAlignment="Center" InputMethod.IsInputMethodEnabled="False" />

<think>好的,用户问的是如何在WPF中设置文本框只能输入数字。之前他们问过关于小数的问题,现在这个问题更简单一些,只需要限制为数字输入。首先,我需要回顾之前的回答,确保这次回答的连贯性。 用户可能是在开发一个需要数值输入的应用程序,比如计算器或者表单输入。他们需要确保用户只能输入数字,避免无效数据。这时候,我需要考虑不同的方法来实现这个功能。 方法一:PreviewTextInput事件结合正则表达式。这和之前处理小数的方法类似,但这次不需要小数点,所以正则表达式应该只允许数字。需要注意退格键和其他控制键的处理,比如是否允许复制粘贴。 方法二:使用数据验证规则,类似之前的小数验证,但这里只需要检查是否为整数。不过数据绑定的方法可能在实时性上不如事件处理,因为绑定验证通常在失去焦点时才触发,而用户可能需要即时反馈。 另外,用户可能没有提到负数,但有时候需要考虑负号。这时候是否需要添加负号的支持?可能需要进一步询问用户需求,但问题中没有提到,所以先默认处理正整数,然后在注意事项里说明如何扩展。 还要考虑粘贴操作,用户可能通过粘贴输入非数字字符,所以需要处理DataObject.Pasting事件,同样用正则过滤。 另外,是否有其他方法,比如使用MaskedTextBox或者第三方库?不过原生的WPF没有MaskedTextBox,可能需要使用其他库,但用户可能希望使用内置的功能,所以暂时不提。 代码示例部分需要展示XAML和C#代码,确保用户能够直接复制使用。同时,注意事项要提醒用户可能的扩展,比如负数、文化差异等。 相关问题方面,应该延续之前的思路,比如如何允许负数、处理小数点、精度限制、XAML掩码等。但这次的问题是关于数字,所以相关问题可能包括整数的限制,负数,以及结合之前的输入验证方法。 总结下来,回答的结构应该是两种方法,代码示例,注意事项,相关问题。需要确保回答准确,并且与之前的问题保持一致的风格和深度。</think>在WPF中限制文本框仅允许输入数字,可通过以下两种方式实现: --- ### 方法1:使用 **PreviewTextInput + 正则表达式** ```xml <!-- XAML --> <TextBox x:Name="NumberTextBox" PreviewTextInput="NumberTextBox_PreviewTextInput" DataObject.Pasting="NumberTextBox_Pasting"/> ``` ```csharp // C# private void NumberTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { // 仅允许数字和退格键 e.Handled = !Regex.IsMatch(e.Text, @"^\d+$"); } private void NumberTextBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(string))) { string text = (string)e.DataObject.GetData(typeof(string)); if (!Regex.IsMatch(text, @"^\d+$")) e.CancelCommand(); } else e.CancelCommand(); } ``` --- ### 方法2:使用 **数据绑定 + 验证规则** ```xml <!-- XAML --> <TextBox> <TextBox.Text> <Binding Path="IntegerValue" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:IntegerValidationRule/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> ``` ```csharp // 验证规则类 public class IntegerValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { if (int.TryParse(value?.ToString(), out _)) return ValidationResult.ValidResult; return new ValidationResult(false, "请输入有效的整数"); } } ``` --- ### 注意事项 1. **负数支持**:修改正则表达式为 `^-?\d+$` 可允许负数。 2. **文化差异**:不同地区可能使用千分位分隔符(如逗号),需额外处理。 3. **动态更新**:绑定验证规则需配合 `UpdateSourceTrigger=PropertyChanged` 保证实时反馈。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值