因为在 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. vue和iview中native点击事件修饰

    在父组件中给子组件绑定一个原生的事件,就将子组件变成了普通的HTML标签,不加'. native'事件是无法触 在vue中使用iview的dropdownMenu 上单纯的@click也不生效,要写成 ...

  2. 栈和队列问题:设计一个有 getMin 功能的栈

    [知识点] 栈是一个先进后出(FILO-First In Last Out)的数据结构,队列是一种先进先出(FIFO-First In First Out)的数据结构. [题目] 实现一个特殊的栈,在 ...

  3. c++/c DEBUG宏

    #cat log_debug.h #ifdef DEBUG int log_debug(const char *format, ...); #else int log_debug(const char ...

  4. cogs——49. 跳马问题

    49. 跳马问题 水题 dfs裸基础 #include<cstdio> using namespace std; ]={,,,,}, ans,my[]={,-,,-,}; inline v ...

  5. Shell脚本备份文件

    使用crontab 定时备份文件 1. 编辑crontab规则 2. 编写shell脚本 cp -R "/data/www/code" "/home/backup/cod ...

  6. Flask - 模板语言jinja2 和render_template高级用法

    目录 Flask - 模板语言jinja2 和render_template高级用法 一. 字典传递至前端 二. 列表传入前端Jinja2 模板的操作: 三. 大字典传入前端 Jinja2 模板 四. ...

  7. BZOJ 1602 牧场行走

    直接写一波Lca就好了 #include<cstdio> #include<cmath> #include<algorithm> using namespace s ...

  8. 多层gmetad配置

    经实验表明: ①多层gmetad与ganglia版本无关,且可以多版本兼容 ②多层gmetad只有最底层gmetad能保存详细指标,非底层gmetad收集到的都只能是summary信息,当然也许我配置 ...

  9. java后台处理解析json字符串的两种方式

    简单说一下背景 上次后端通过模拟http请求百度地图接口,得到的是一个json字符串,而我只需要其中的某个key对应的value. 当时我是通过截取字符串取的,后来觉得不太合理,今天整理出了两种处理解 ...

  10. 洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...