非原创,整理之前的代码的时候找出来的,可用,与大家分享一下!

   public class NumbericBoxWithZero : NumericBox
{
public NumbericBoxWithZero()
: base()
{ }
protected override void SetTextAndSelection(string text)
{
if (text.IndexOf('.') == -)
{
text = text + ".00";
}
else
{
if (text.IndexOf('.') != text.Length - )
{
string front = text.Substring(,text.IndexOf('.'));
string back = text.Substring(text.IndexOf('.') + , text.Length - text.IndexOf('.') - );
if(back != "")
text = string.Format("{0}.{1:d2}",front,int.Parse(back));
}
}
base.SetTextAndSelection(text);
}
}
/// <summary>
/// NumericBox功能设计
/// 只能输入0-9的数字和至多一个小数点;
///能够屏蔽通过非正常途径的不正确输入(输入法,粘贴等);
///能够控制小数点后的最大位数,超出位数则无法继续输入;
///能够选择当小数点数位数不足时是否补0;
///去除开头部分多余的0(为方便处理,当在开头部分输入0时,自动在其后添加一个小数点);
///由于只能输入一个小数点,当在已有的小数点前再次按下小数点,能够跳过小数点;
/// </summary>
public class NumericBox : TextBox
{
#region Dependency Properties
/// <summary>
/// 最大小数点位数
/// </summary>
public int MaxFractionDigits
{
get { return (int)GetValue(MaxFractionDigitsProperty); }
set { SetValue(MaxFractionDigitsProperty, value); }
}
// Using a DependencyProperty as the backing store for MaxFractionDigits. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaxFractionDigitsProperty =
DependencyProperty.Register("MaxFractionDigits", typeof(int), typeof(NumericBox), new PropertyMetadata()); /// <summary>
/// 不足位数是否补零
/// </summary>
public bool IsPadding
{
get { return (bool)GetValue(IsPaddingProperty); }
set { SetValue(IsPaddingProperty, value); }
}
// Using a DependencyProperty as the backing store for IsPadding. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsPaddingProperty =
DependencyProperty.Register("IsPadding", typeof(bool), typeof(NumericBox), new PropertyMetadata(true)); #endregion public NumericBox()
{
TextBoxFilterBehavior behavior = new TextBoxFilterBehavior();
behavior.TextBoxFilterOptions = TextBoxFilterOptions.Numeric | TextBoxFilterOptions.Dot;
Interaction.GetBehaviors(this).Add(behavior);
this.TextChanged += new TextChangedEventHandler(NumericBox_TextChanged);
} /// <summary>
/// 设置Text文本以及光标位置
/// </summary>
/// <param name="text"></param>
protected virtual void SetTextAndSelection(string text)
{
//保存光标位置
int selectionIndex = this.SelectionStart;
this.Text = text;
//恢复光标位置 系统会自动处理光标位置超出文本长度的情况
this.SelectionStart = selectionIndex;
} /// <summary>
/// 去掉开头部分多余的0
/// </summary>
private void TrimZeroStart()
{
string resultText = this.Text;
//计算开头部分0的个数
int zeroCount = ;
foreach (char c in this.Text)
{
if (c == '') { zeroCount++; }
else { break; }
} //当前文本中包含小数点
if (this.Text.Contains('.'))
{
//0后面跟的不是小数点,则删除全部的0
if (this.Text[zeroCount] != '.')
{
resultText = this.Text.TrimStart('');
}
//否则,保留一个0
else if (zeroCount > )
{
resultText = this.Text.Substring(zeroCount - );
}
}
//当前文本中不包含小数点,则保留一个0,并在其后加一个小数点,并将光标设置到小数点前
else if (zeroCount > )
{
resultText = "0." + this.Text.TrimStart('');
this.SelectionStart = ;
} SetTextAndSelection(resultText);
} void NumericBox_TextChanged(object sender, TextChangedEventArgs e)
{
int decimalIndex = this.Text.IndexOf('.');
if (decimalIndex >= )
{
//小数点后的位数
int lengthAfterDecimal = this.Text.Length - decimalIndex - ;
if (lengthAfterDecimal > MaxFractionDigits)
{
SetTextAndSelection(this.Text.Substring(, this.Text.Length - (lengthAfterDecimal - MaxFractionDigits)));
}
else if (IsPadding)
{
SetTextAndSelection(this.Text.PadRight(this.Text.Length + MaxFractionDigits - lengthAfterDecimal, ''));
}
}
TrimZeroStart();
}
}
/// <summary>
/// TextBox筛选行为,过滤不需要的按键
/// </summary>
public class TextBoxFilterBehavior : Behavior<TextBox>
{
private string _prevText = string.Empty;
public TextBoxFilterBehavior()
{
}
#region Dependency Properties
/// <summary>
/// TextBox筛选选项,这里选择的为过滤后剩下的按键
/// 控制键不参与筛选,可以多选组合
/// </summary>
public TextBoxFilterOptions TextBoxFilterOptions
{
get { return (TextBoxFilterOptions)GetValue(TextBoxFilterOptionsProperty); }
set { SetValue(TextBoxFilterOptionsProperty, value); }
} // Using a DependencyProperty as the backing store for TextBoxFilterOptions. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextBoxFilterOptionsProperty =
DependencyProperty.Register("TextBoxFilterOptions", typeof(TextBoxFilterOptions), typeof(TextBoxFilterBehavior), new PropertyMetadata(TextBoxFilterOptions.None));
#endregion protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.KeyDown += new KeyEventHandler(AssociatedObject_KeyDown);
this.AssociatedObject.TextChanged += new TextChangedEventHandler(AssociatedObject_TextChanged);
} protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.KeyDown -= new KeyEventHandler(AssociatedObject_KeyDown);
this.AssociatedObject.TextChanged -= new TextChangedEventHandler(AssociatedObject_TextChanged);
} #region Events /// <summary>
/// 处理通过其它手段进行的输入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
{
//如果符合规则,就保存下来
if (IsValidText(this.AssociatedObject.Text))
{
_prevText = this.AssociatedObject.Text;
}
//如果不符合规则,就恢复为之前保存的值
else
{
int selectIndex = this.AssociatedObject.SelectionStart - (this.AssociatedObject.Text.Length - _prevText.Length);
this.AssociatedObject.Text = _prevText; if (selectIndex < )
selectIndex = ; this.AssociatedObject.SelectionStart = selectIndex;
} } /// <summary>
/// 处理按键产生的输入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void AssociatedObject_KeyDown(object sender, KeyEventArgs e)
{
bool handled = true;
//不进行过滤
if (TextBoxFilterOptions == TextBoxFilterOptions.None ||
KeyboardHelper.IsControlKeys(e.Key))
{
handled = false;
}
//数字键
if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Numeric))
{
handled = !KeyboardHelper.IsDigit(e.Key);
}
//小数点
//if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Dot))
//{
// handled = !(KeyboardHelper.IsDot(e.Key, e.PlatformKeyCode) && !_prevText.Contains("."));
// if (KeyboardHelper.IsDot(e.Key, e.PlatformKeyCode) && _prevText.Contains("."))
// {
// //如果输入位置的下一个就是小数点,则将光标跳到小数点后面
// if (this.AssociatedObject.SelectionStart< this.AssociatedObject.Text.Length && _prevText[this.AssociatedObject.SelectionStart] == '.')
// {
// this.AssociatedObject.SelectionStart++;
// }
// }
//}
if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Dot))
{
handled = !(KeyboardHelper.IsDot(e.Key) && !_prevText.Contains("."));
if (KeyboardHelper.IsDot(e.Key) && _prevText.Contains("."))
{
//如果输入位置的下一个就是小数点,则将光标跳到小数点后面
if (this.AssociatedObject.SelectionStart < this.AssociatedObject.Text.Length && _prevText[this.AssociatedObject.SelectionStart] == '.')
{
this.AssociatedObject.SelectionStart++;
}
}
}
//字母
if (handled && TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Character))
{
handled = !KeyboardHelper.IsDot(e.Key);
}
e.Handled = handled;
} #endregion #region Private Methods
/// <summary>
/// 判断是否符合规则
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
private bool IsValidChar(char c)
{
if (TextBoxFilterOptions == TextBoxFilterOptions.None)
{
return true;
}
else if (TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Numeric) &&
'' <= c && c <= '')
{
return true;
}
else if (TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Dot) &&
c == '.')
{
return true;
}
else if (TextBoxFilterOptions.ContainsOption(TextBoxFilterOptions.Character))
{
if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
{
return true;
}
}
return false;
} /// <summary>
/// 判断文本是否符合规则
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private bool IsValidText(string text)
{
//只能有一个小数点
if (text.IndexOf('.') != text.LastIndexOf('.'))
{
return false;
}
foreach (char c in text)
{
if (!IsValidChar(c))
{
return false;
}
}
return true;
}
#endregion
}
/// <summary>
/// TextBox筛选选项
/// </summary>
[Flags]
public enum TextBoxFilterOptions
{
/// <summary>
/// 不采用任何筛选
/// </summary>
None = ,
/// <summary>
/// 数字类型不参与筛选
/// </summary>
Numeric = ,
/// <summary>
/// 字母类型不参与筛选
/// </summary>
Character = ,
/// <summary>
/// 小数点不参与筛选
/// </summary>
Dot = ,
/// <summary>
/// 其它类型不参与筛选
/// </summary>
Other =
} /// <summary>
/// TextBox筛选选项枚举扩展方法
/// </summary>
public static class TextBoxFilterOptionsExtension
{
/// <summary>
/// 在全部的选项中是否包含指定的选项
/// </summary>
/// <param name="allOptions">所有的选项</param>
/// <param name="option">指定的选项</param>
/// <returns></returns>
public static bool ContainsOption(this TextBoxFilterOptions allOptions, TextBoxFilterOptions option)
{
return (allOptions & option) == option;
}
}
/// <summary>
/// 键盘操作帮助类
/// </summary>
public class KeyboardHelper
{
/// <summary>
/// 键盘上的句号键
/// </summary>
public const int OemPeriod = ; #region Fileds /// <summary>
/// 控制键
/// </summary>
private static readonly List<Key> _controlKeys = new List<Key>
{
Key.Back,
Key.CapsLock,
//Key.Ctrl,
Key.Down,
Key.End,
Key.Enter,
Key.Escape,
Key.Home,
Key.Insert,
Key.Left,
Key.PageDown,
Key.PageUp,
Key.Right,
//Key.Shift,
Key.Tab,
Key.Up
}; #endregion /// <summary>
/// 是否是数字键
/// </summary>
/// <param name="key">按键</param>
/// <returns></returns>
public static bool IsDigit(Key key)
{
bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != ;
bool retVal;
//按住shift键后,数字键并不是数字键
if (key >= Key.D0 && key <= Key.D9 && !shiftKey)
{
retVal = true;
}
else
{
retVal = key >= Key.NumPad0 && key <= Key.NumPad9;
}
return retVal;
} /// <summary>
/// 是否是控制键
/// </summary>
/// <param name="key">按键</param>
/// <returns></returns>
public static bool IsControlKeys(Key key)
{
return _controlKeys.Contains(key);
} /// <summary>
/// 是否是小数点
/// Silverlight中无法识别问号左边的那个小数点键
/// 只能识别小键盘中的小数点
/// </summary>
/// <param name="key">按键</param>
/// <returns></returns>
public static bool IsDot(Key key)
{
bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != ;
bool flag = false;
if (key == Key.Decimal)
{
flag = true;
}
if (key == Key.OemPeriod && !shiftKey)
{
flag = true;
}
return flag;
} /// <summary>
/// 是否是小数点
/// </summary>
/// <param name="key">按键</param>
/// <param name="keyCode">平台相关的按键代码</param>
/// <returns></returns>
public static bool IsDot(Key key, int keyCode)
{ //return IsDot(key) || (key == Key.Unknown && keyCode == OemPeriod);
return IsDot(key) || (keyCode == OemPeriod);
} /// <summary>
/// 是否是字母键
/// </summary>
/// <param name="key">按键</param>
/// <returns></returns>
public static bool IsCharacter(Key key)
{
return key >= Key.A && key <= Key.Z;
}
}

使用:

 <Controls:NumericBox Grid.Column="3" Grid.Row="11"
Width="200" Height="30" Text="{Binding old,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
CustomTextWrapping="NoWrap" CustomTextHeight="26" CustomTextWidth="170"
BgForeground="{StaticResource DialogTextBgForeground}"
CustomBorderColor="{StaticResource DialogTextBorderColor}" CustomBgColor="{StaticResource DialogTextBgColor}" >
<i:Interaction.Behaviors>
<Controls:TextBoxFilterBehavior TextBoxFilterOptions="Numeric"/> <!--可以选择输入数字,小数点等-->
</i:Interaction.Behaviors>
</Controls:NumericBox>

WPF 自定义TextBox,可控制键盘输入内容的更多相关文章

  1. WPF自定义TextBox及ScrollViewer

    原文:WPF自定义TextBox及ScrollViewer 寒假过完,在家真心什么都做不了,可能年龄大了,再想以前那样能专心坐下来已经不行了.回来第一件事就是改了项目的一个bug,最近又新增了一个新的 ...

  2. 在ie9下在textbox框里面输入内容按enter键会触发按钮的事件

    问题 在ie下,如果存在有button标签,如果在textbox里面输入内容,按下enter键,则会触发第一个按钮的click事件,经过测试,在IE10以及以下的都存在这个问题 原因 浏览器默认行为不 ...

  3. WPF 自定义TextBox带水印控件,可设置圆角

    一.简单设置水印TextBox控件,废话不多说看代码: <TextBox TextWrapping="Wrap" Margin="10" Height=& ...

  4. WPF 中textBox实现只输入数字

    刚学到 通过本方法可以使文本框只能输入或复制入数字  对于数量类输入文本框比较有用 金额类只需小改动也可实现 以TextBox txtCount为例 添加TextChanged事件 代码如下 priv ...

  5. WPF 自定义TextBox

    1.TextBox前加图标. 效果: <TextBox Width="300" Height="30" Style="{StaticResour ...

  6. WPF 限制Textbox输入的内容

    限制文本框TextBox的输入内容,在很多场景都有应用.举个例子,现在文本框中,只能输入0.1.2.3.4.5.6.7.8.9.“|”这11个字符. 限制输入0-9很容易实现,关键是这个“|”符号.它 ...

  7. Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中

    功能:在textbox中输入内容,动态从数据库模糊查询显示到下拉框中,以供选择 1.建立一aspx页面,html代码 <HTML> <HEAD> <title>We ...

  8. WPF中TextBox限制输入不起作用的问题

    最近再用textbox做限制输入时遇到一个莫名其妙的问题: 首先看代码: <TextBox  Name="txtip1" Height="40" Widt ...

  9. VC++6.0/MFC 自定义edit 限制输入内容 响应复制粘贴全选剪切的功能

    Ctrl组合键ASCII码 ^Z代表Ctrl+z                     ASCII值 控制字符  ASCII值 控制字符  ASCII值 控制字符  ASCII值 控制字符0(00) ...

随机推荐

  1. 【微信开发】常用 api

    [微信开发]api 一. 开发文档 二. 调试工具 三. api 1. 获取 token - https://api.weixin.qq.com/cgi-bin/token?grant_type=cl ...

  2. 数据转移发现font有问题

    本地正常 以为是mime.types没有 但是发现是存在的  然后根据提示百度了很久都没有解决 解决: 去字体官网下载改字体文件下来 上传到服务器 发现可以正常访问 说明不是服务器的问题 有个提示 i ...

  3. KeepAlived主备/主主模型高可用Nginx

    部署准备: 两台CentOS 7主机HA1和HA2 CentOS 7 基于rpm包安装Nginx: 由于Base源中没有Nginx,所以要安装EPEL源,命令如下: wget http://dl.fe ...

  4. c++的默认构造函数 VS 深拷贝(值拷贝) 与 浅拷贝(位拷贝)

    C++默认为类生成了四个缺省函数: A(void); // 缺省的无参数构造函数 A(const A &a); // 缺省的拷贝构造函数 ~A(void); // 缺省的析构函数 A & ...

  5. Hibernate持久化类属性映射

    Hibernate充当应用程序和数据库之间的中间件,实现二者之间的交互操作,他对JDBC进行了封装,以完全面向对象的方式来操作数据. 适用于有多个数据源的情况下,不必去考虑不同数据源的操作差异. Hi ...

  6. js进阶

    js在实例化对象后,可以对这个对象增加属性和属性值,并且还可以通过delete一元操作符来删除对象的属性. var o = new Object(); o.name = "langsin&q ...

  7. python 类变量 在多线程下的共享与释放问题

    最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...

  8. [Linux] 结构化命令 if

    语法结构如下: 1. if-then语句 # if-then语句 if command #根据conmmand的退出状态码,选择执行语句 then commands fi e.g. #!usr/bin ...

  9. 使用ycsb测试cassandra

    参考 https://github.com/cloudius-systems/osv/wiki/Benchmarking-Cassandra-and-other-NoSQL-databases-wit ...

  10. android接收短信——framework处理流程(android 5.1)

    modem层不懂,所以直接从RIL.java开始.以电信卡接收短信为例 modem通知RIL.java中的 RILReceiver处理接收信息 class RILReceiver implements ...