因为在 IValueConverter 实现中,当文本不能转换为目标类型时返回 DependencyProperty.UnsetValue ,Validation.GetHasError 返回 true ,为何要绕一个圈让用户输入不能转换的文本,然后再获取错误状态呢?不如直接不让用户输入错误文本,于是写了一个 Behavior 派生类:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity; namespace WpfApplication6
{
public class OnlyDigitalBehavior : Behavior<TextBox>
{
public Type DigitalType
{
get { return (Type)GetValue(DigitalTypeProperty); }
set { SetValue(DigitalTypeProperty, value); }
} public static readonly DependencyProperty DigitalTypeProperty =
DependencyProperty.Register("DigitalType", typeof(Type), typeof(OnlyDigitalBehavior), new PropertyMetadata()); protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.PreviewTextInput += AssociatedObject_PreviewTextInput;
DataObject.AddPastingHandler(this.AssociatedObject, AssociatedObject_Pasting);
InputMethod.SetIsInputMethodEnabled(this.AssociatedObject, false);
} private void AssociatedObject_Pasting(object sender, DataObjectPastingEventArgs e)
{
e.CancelCommand();
} protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.PreviewTextInput -= AssociatedObject_PreviewTextInput;
DataObject.RemovePastingHandler(this.AssociatedObject, AssociatedObject_Pasting);
} private void AssociatedObject_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
{
TextBox textBox = sender as TextBox;
Type digitalType = this.DigitalType;
if (textBox == null)
{
return;
}
if (digitalType == typeof(Int16))
{
Int16 i = ;
if (Int16.TryParse(textBox.Text + e.Text, out i))
{
return;
}
}
else if (digitalType == typeof(Int32))
{
Int32 i = ;
if (Int32.TryParse(textBox.Text + e.Text, out i))
{
return;
}
}
else if (digitalType == typeof(Int64))
{
Int64 i = ;
if (Int64.TryParse(textBox.Text + e.Text, out i))
{
return;
}
}
else if (digitalType == typeof(double))
{
double d = ;
if (double.TryParse(textBox.Text + e.Text, out d))
{
return;
}
}
else if (digitalType == typeof(decimal))
{
decimal d = ;
if (decimal.TryParse(textBox.Text + e.Text, out d))
{
return;
}
}
e.Handled = true;
}
}
}

InputMethod.SetIsInputMethodEnabled(this.AssociatedObject, false); 作用是屏蔽输入法。

以下是测试View:

 <Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:WpfApplication6"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBlock Margin="3">Int16</TextBlock>
<TextBox Margin="3">
<i:Interaction.Behaviors>
<local:OnlyDigitalBehavior DigitalType="{x:Type sys:Int16}" />
</i:Interaction.Behaviors>
</TextBox>
<TextBlock Margin="3">Int32</TextBlock>
<TextBox Margin="3">
<i:Interaction.Behaviors>
<local:OnlyDigitalBehavior DigitalType="{x:Type sys:Int32}" />
</i:Interaction.Behaviors>
</TextBox>
<TextBlock Margin="3">Int64</TextBlock>
<TextBox Margin="3">
<i:Interaction.Behaviors>
<local:OnlyDigitalBehavior DigitalType="{x:Type sys:Int64}" />
</i:Interaction.Behaviors>
</TextBox>
<TextBlock Margin="3">Double</TextBlock>
<TextBox Margin="3">
<i:Interaction.Behaviors>
<local:OnlyDigitalBehavior DigitalType="{x:Type sys:Double}" />
</i:Interaction.Behaviors>
</TextBox>
<TextBlock Margin="3">Decimal</TextBlock>
<TextBox Margin="3">
<i:Interaction.Behaviors>
<local:OnlyDigitalBehavior DigitalType="{x:Type sys:Decimal}" />
</i:Interaction.Behaviors>
</TextBox>
</StackPanel>
</Window>

如果大家有更好的实现方法欢迎赐教!

再来一个支持粘贴的:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity; namespace WpfApplication6
{
public class OnlyDigitalBehavior : Behavior<TextBox>
{
private string lastRight = null; public Type DigitalType
{
get { return (Type)GetValue(DigitalTypeProperty); }
set { SetValue(DigitalTypeProperty, value); }
} public static readonly DependencyProperty DigitalTypeProperty =
DependencyProperty.Register("DigitalType", typeof(Type), typeof(OnlyDigitalBehavior), new PropertyMetadata()); protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.TextChanged += AssociatedObject_TextChanged;
InputMethod.SetIsInputMethodEnabled(this.AssociatedObject, false);
} protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
} private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Type digitalType = this.DigitalType;
if (textBox == null)
{
return;
}
if ((IsDigital(digitalType,textBox.Text) || string.IsNullOrEmpty(textBox.Text)) && lastRight != textBox.Text)
{
lastRight = textBox.Text;
}
else if (textBox.Text != lastRight)
{
textBox.Text = lastRight;
textBox.SelectionStart = textBox.Text.Length;
}
} private bool IsDigital(Type targetType,string digitalString)
{
if (targetType == typeof(Int16))
{
Int16 i = ;
if (Int16.TryParse(digitalString, out i))
{
return true;
}
}
else if (targetType == typeof(Int32))
{
Int32 i = ;
if (Int32.TryParse(digitalString, out i))
{
return true;
}
}
else if (targetType == typeof(Int64))
{
Int64 i = ;
if (Int64.TryParse(digitalString, out i))
{
return true;
}
}
else if (targetType == typeof(double))
{
double d = ;
if (double.TryParse(digitalString, out d))
{
return true;
}
}
else if (targetType == typeof(decimal))
{
decimal d = ;
if (decimal.TryParse(digitalString, out d))
{
return true;
}
}
return false;
}
}
}

WPF TextBox 仅允许输入数字的更多相关文章

  1. c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字

    TextBox只允许输入数字,最大长度为10 //TextBox.ShortcutsEnabled为false 禁止右键和Ctrl+v private void txtNumber_KeyPress( ...

  2. 2019-3-22c# TextBox只允许输入数字,禁用右键粘贴,允许Ctrl+v粘贴数字

    TextBox 禁止复制粘贴 ShortcutsEnabled =false TextBox只允许输入数字,最大长度为10 //TextBox.ShortcutsEnabled为false 禁止右键和 ...

  3. C#的winform中控制TextBox中只能输入数字

    C#的winform中控制TextBox中只能输入数字 private void textBox3_KeyPress(object sender, System.Windows.Forms.KeyPr ...

  4. C#中设置TextBox控件中仅可以输入数字且设置上限

    首先设置只可以输入数字: 首先设置TextBox控件的KeyPress事件:当用户按下的键盘的键不在数字位的话,就禁止输入 private void textBox1_KeyPress(object ...

  5. 04实现累加和计算功能并且实现textbox不允许输入数字以外的字符但不包括退格键同时不允许第一个数值为0

    private void button1_Click(object sender, EventArgs e) { double number1, number2; if (double.TryPars ...

  6. C#-WinForm-Winform TextBox中只能输入数字的几种常用方法(C#)

    方法一: private void tBox_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == 0x20) e.KeyCh ...

  7. Winform TextBox中只能输入数字的几种常用方法(C#)

    方法一: private void tBox_KeyPress(object sender, KeyPressEventArgs e) { ; //禁止空格键 )) return; //处理负数 if ...

  8. winform中如何在TextBox中只能输入数字(可以带小数点)

    可以采用像web表单验证的方式,利用textbox的TextChanged事件,每当textbox内容变化时,调用正则表达式的方法验证,用一个label在text后面提示输入错误,具体代码如下: pr ...

  9. input输入框限制仅能输入数字且规定数字长度(使用与输入手机号)

    现在越来越多的账户名使用手机号来登录,为了减少前后端的交互,需要用户在输入时就要进行格式的判断, 目前的常规办法是,在输入完成后进行判断. 下面的方法是在输入时就规定只能输入数字,其他格式的字符是无法 ...

随机推荐

  1. Burnside引理和polay计数 poj2409 Let it Bead

    题目描述 "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you ...

  2. uva 1585 Score(Uva-1585)

    vj:https://vjudge.net/problem/UVA-1585 不多说水题一个o一直加x就加的变为0 我的代码 #include <iostream> #include &l ...

  3. Linux常用解压缩命令

    压 缩:tar -jcv -f filename.tar.bz2 要被压缩的文件或目录名称 查 询:tar -jtv -f filename.tar.bz2 解压缩:tar -jxv -f filen ...

  4. models中,字段参数limit_choices_to的用法

    这里,在使用 ModelForm 渲染前端页面的前提下,对于 models 中的 ManyToManyField 类型字段会在 ModelForm 中被转化为 ModelMultipleChoiceF ...

  5. Django REST framework - 解析器和渲染器

    目录 Django REST framework - 解析器和渲染器 解析器 Django中的数据解析 DRF中的解析器 渲染器 Django REST framework - 解析器和渲染器 解析器 ...

  6. 第二节:numpy之数组切片、数据类型转换、随机数组

  7. Python 7 列表 for 字典,嵌套

    列表: 基本格式:变量名 = [元素1,元素2,元素3] 创建:A = ['访客','admin',19]  或  A = list(['armin','admin',19]),  后者更倾向于转换为 ...

  8. [国家集训队2012]tree(陈立杰)

    [国家集训队2012]tree(陈立杰) 题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. INPUT 第一行V,E,need分别表示 ...

  9. 对SHH的公钥和私钥的简单理解

    SSH是在应用层和传输层基础上的安全协议 SSH提供了两种级别的安全验证: 第一基于密码的安全验证:账号.密码,但可能有别的服务器冒充真正的服务器,无法避免被“中间人”攻击(man-in-the-mi ...

  10. 选择客栈(codevs 1135)

    题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...