因为在 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. 【剑指Offer】66、机器人的运动范围

      题目描述:   地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时 ...

  2. 28.function_score自定义相关度分数算法

    我们可以做到自定义一个function_score函数,自己将某个field的值,跟es内置算出来的分数进行运算,然后由自己指定的field来进行分数的增强     一.准备数据 给所有的帖子数据增加 ...

  3. copy the content of a file muliptle times and save as ordered files:

    input: transient.case outputs: transient_1.case, transient_2.case,...transient_101.case ********** n ...

  4. noip模拟赛 PA

    分析:很显然这是一道搜索题,可能是由于我的搜索打的太不美观了,这道题又WA又T......如果对每一个询问都做一次bfs是肯定会T的,注意到前70%的数据范围,N的值都相等,我们可以把给定N的所有情况 ...

  5. [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]

    题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...

  6. 洛谷 P2548 [AHOI2004]智能探险车

    P2548 [AHOI2004]智能探险车 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 复制 4 3 sunny plain full many sunny moun ...

  7. ZooKeeper的配置文件优化性能(转)

    一.前言 ZooKeeper的功能特性通过ZooKeeper配置文件来进行控制管理( zoo.cfg配置文件). ZooKeeper这样的设计其实是有它自身的原因的.通过前面对ZooKeeper的配置 ...

  8. Oracle批量恢复drop操作删除的表、索引等对象

    /**********************************************************************查询Drop操作删除的对象select * from re ...

  9. saltstack结合Elasticsearch来做salt运行结果展现

    salt尽管好用可是机器管理的越来越多,通过cli的结果输出方式查看运行结果越来越多不能满足我的需求.并且作为一个推动运维自己主动化的攻城狮,使用这样的人眼查看运行结果的方式简直土到掉渣.尽管别人看起 ...

  10. Java:Socket通信

    Socket通常也称作"套接字".用于描写叙述IP地址和port,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ServerS ...