WPF 自定义数字文本框:NumericBox
由于项目需要,最近写了一个数字输入文本框,在此作个备忘。
1.代码调用
<controls:NumericBox Height="32" Width="80"
MinValue ="0"
MaxValue="100"
Digits ="0"
CurValue="{Binding LabelSize, Mode=TwoWay}" >
</controls:NumericBox>
2.样式(InputMethod.IsInputMethodEnabled项设置为false后可以屏蔽输入法)
<Style TargetType="{x:Type local:NumericBox}" BasedOn="{StaticResource MetroTextBox}">
<Setter Property="InputMethod.IsInputMethodEnabled" Value="False" />
</Style>
3.后台逻辑
public class NumericBox : TextBox
{
#region DependencyProperty
private const double CURVALUE = 0; //当前值
private const double MINVALUE = double.MinValue; //最小值
private const double MAXVALUE = double.MaxValue; //最大值
private const int DIGITS = 15; //小数点精度
public static readonly DependencyProperty CurValueProperty;
public static readonly DependencyProperty MinValueProperty;
public static readonly DependencyProperty MaxValueProperty;
public static readonly DependencyProperty DigitsProperty;
public double CurValue
{
get
{
return (double)GetValue(CurValueProperty);
}
set
{
double v = value;
if (value < MinValue)
{
v = MinValue;
}
else if (value > MaxValue)
{
v = MaxValue;
}
v = Math.Round(v, Digits);
SetValue(CurValueProperty, v);
// if do not go into OnCurValueChanged then force update ui
if (v != value)
{
this.Text = v.ToString();
}
}
}
public double MinValue
{
get
{
return (double)GetValue(MinValueProperty);
}
set
{
SetValue(MinValueProperty, value);
}
}
public double MaxValue
{
get
{
return (double)GetValue(MaxValueProperty);
}
set
{
SetValue(MaxValueProperty, value);
}
}
public int Digits
{
get
{
return (int)GetValue(DigitsProperty);
}
set
{
int digits = value;
if (digits <= 0)
{
digits = 0;
}
if (digits > 15)
{
digits = 15;
}
SetValue(DigitsProperty, value);
}
}
static NumericBox()
{
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(CURVALUE, new PropertyChangedCallback(OnCurValueChanged));
CurValueProperty = DependencyProperty.Register("CurValue", typeof(double), typeof(NumericBox), metadata);
metadata = new FrameworkPropertyMetadata(MINVALUE, new PropertyChangedCallback(OnMinValueChanged));
MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(NumericBox), metadata);
metadata = new FrameworkPropertyMetadata(MAXVALUE, new PropertyChangedCallback(OnMaxValueChanged));
MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(NumericBox), metadata);
metadata = new FrameworkPropertyMetadata(DIGITS, new PropertyChangedCallback(OnDigitsChanged));
DigitsProperty = DependencyProperty.Register("Digits", typeof(int), typeof(NumericBox), metadata);
}
private static void OnCurValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
double value = (double)e.NewValue;
NumericBox numericBox = (NumericBox)sender;
numericBox.Text = value.ToString();
}
private static void OnMinValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
double minValue = (double)e.NewValue;
NumericBox numericBox = (NumericBox)sender;
numericBox.MinValue = minValue;
}
private static void OnMaxValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
double maxValue = (double)e.NewValue;
NumericBox numericBox = (NumericBox)sender;
numericBox.MaxValue = maxValue;
}
private static void OnDigitsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
int digits = (int)e.NewValue;
NumericBox numericBox = (NumericBox)sender;
numericBox.CurValue = Math.Round(numericBox.CurValue, digits);
numericBox.MinValue = Math.Round(numericBox.MinValue, digits);
numericBox.MaxValue = Math.Round(numericBox.MaxValue, digits);
}
#endregion
public NumericBox()
{
this.TextChanged += NumericBox_TextChanged;
this.PreviewKeyDown += NumericBox_KeyDown;
this.LostFocus += NumericBox_LostFocus;
DataObject.AddPastingHandler(this, NumericBox_Pasting);
}
void NumericBox_TextChanged(object sender, TextChangedEventArgs e)
{
NumericBox numericBox = sender as NumericBox;
if (string.IsNullOrEmpty(numericBox.Text))
{
return;
}
TrimZeroStart();
double value = MinValue;
if (!Double.TryParse(numericBox.Text, out value))
{
return;
}
if (value != this.CurValue)
{
this.CurValue = value;
}
}
void NumericBox_KeyDown(object sender, KeyEventArgs e)
{
Key key = e.Key;
if(IsControlKeys(key))
{
return;
}
else if (IsDigit(key))
{
return;
}
else if (IsSubtract(key)) //-
{
TextBox textBox = sender as TextBox;
string str = textBox.Text;
if (str.Length > 0 && textBox.SelectionStart != 0)
{
e.Handled = true;
}
}
else if (IsDot(key)) //point
{
if (this.Digits > 0)
{
TextBox textBox = sender as TextBox;
string str = textBox.Text;
if (str.Contains('.') || str == "-")
{
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
void NumericBox_LostFocus(object sender, RoutedEventArgs e)
{
NumericBox numericBox = sender as NumericBox;
if (string.IsNullOrEmpty(numericBox.Text))
{
numericBox.Text = this.CurValue.ToString();
}
}
private void NumericBox_Pasting(object sender, DataObjectPastingEventArgs e)
{
e.CancelCommand();
}
private static readonly List<Key> _controlKeys = new List<Key>
{
Key.Back,
Key.CapsLock,
Key.Down,
Key.End,
Key.Enter,
Key.Escape,
Key.Home,
Key.Insert,
Key.Left,
Key.PageDown,
Key.PageUp,
Key.Right,
Key.Tab,
Key.Up
};
public static bool IsControlKeys(Key key)
{
return _controlKeys.Contains(key);
}
public static bool IsDigit(Key key)
{
bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
bool retVal;
if (key >= Key.D0 && key <= Key.D9 && !shiftKey)
{
retVal = true;
}
else
{
retVal = key >= Key.NumPad0 && key <= Key.NumPad9;
}
return retVal;
}
public static bool IsDot(Key key)
{
bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
bool flag = false;
if (key == Key.Decimal)
{
flag = true;
}
if (key == Key.OemPeriod && !shiftKey)
{
flag = true;
}
return flag;
}
public static bool IsSubtract(Key key)
{
bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;
bool flag = false;
if (key == Key.Subtract)
{
flag = true;
}
if (key == Key.OemMinus && !shiftKey)
{
flag = true;
}
return flag;
}
private void TrimZeroStart()
{
if(this.Text.Length == 1)
{
return;
}
string resultText = this.Text;
int zeroCount = 0;
foreach (char c in this.Text)
{
if (c == '0') { zeroCount++; }
else { break; }
}
if (zeroCount == 0)
{
return;
}
if (this.Text.Contains('.'))
{
if (this.Text[zeroCount] != '.')
{
resultText = this.Text.TrimStart('0');
}
else if (zeroCount > 1)
{
resultText = this.Text.Substring(zeroCount - 1);
}
}
else if (zeroCount > 0)
{
resultText = this.Text.TrimStart('0');
}
}
}
WPF 自定义数字文本框:NumericBox的更多相关文章
- C#Winform使用扩展方法自定义富文本框(RichTextBox)字体颜色
在利用C#开发Winform应用程序的时候,我们有可能使用RichTextBox来实现实时显示应用程序日志的功能,日志又分为:一般消息,警告提示 和错误等类别.为了更好地区分不同类型的日志,我们需要使 ...
- C# 全选中数字文本框内容
/// <summary> /// 全选中数字文本框内容 /// </summary> /// <param name=&quo ...
- [WPF]实现TextBox文本框单击全选
原文:[WPF]实现TextBox文本框单击全选 /// <summary> /// Void:设置获取焦点时全选文本 /// </summary&g ...
- WPF自定义数字输入框控件
要求:只能输入数字和小数点,可以设置最大值,最小值,小数点前长度,小数点后长度(支持绑定设置): 代码如下: using System; using System.Collections.Generi ...
- [C# WPF] 关于将文本框竖起来(旋转文字)
xx.xmal.cs 后台代码中动态添加控件到 UI 文字显示在一个 Canvas 中(定位用Canvas.SetLeft() / Canvas.SetTop() ), 为了实现排版效果,可适当在 T ...
- WPF 自定义文本框输入法 IME 跟随光标
本文告诉大家在 WPF 写一个自定义的文本框,如何实现让输入法跟随光标 本文非小白向,本文适合想开发自定义的文本框,从底层开始开发的文本库的伙伴.在开始之前,期望了解了文本库开发的基础知识 本文实现的 ...
- [JS] 文本框判断输入的内容是否为数字
可以通过触发文本框的onchange事件来对输入的内容进行判断是否为数字 文本框的属性设置: 把onchange的属性对应的js函数写好即可 参数传输的是当前控件的value值,即text值 < ...
- JS学习笔记 - 自定义右键菜单、文本框只能输入数字
<script> // 事件总共有2个部分, //1.点击鼠标右键的表现 oncontextmenu 2.点击鼠标左键的表现(即普通点击onclick) // 点击右键,div位置定位到鼠 ...
- JavaScript 自定义文本框光标——初级版
文本框(input或textarea)的光标无法修改样式(除了通过color修改光标颜色).但笔者希望个人创建自己的网站时,文本框的光标有属于自己的风格.所以,尝试模拟文本框的光标,设计有自己风格的光 ...
随机推荐
- WCF与Web API 区别
WCF与Web API 区别(应用场景) Web api 主要功能: 支持基于Http verb (GET, POST, PUT, DELETE)的CRUD (create, retrieve, ...
- 你要知道的C与C++的区别
原文:你要知道的C与C++的区别 如果要说C和C++的区别的话,可能可以列出很多方面出来,但是有许多方面的区别是我们学完这两门语言之后就可以 很好的理解和区分的,比如C是面向过程的一门编程语言,C++ ...
- Mongodb操作之查询(循序渐进对比SQL语句)
工具推荐:Robomongo,可自行百度寻找下载源,个人比较推荐这个工具,相比较mongoVUE则更加灵活. 集合简单查询方法 mongodb语法:db.collection.find() //co ...
- 移植MonkeyRunner的图片对比和获取子图功能的实现-Appium篇
如果你的目标测试app有很多imageview组成的话,这个时候monkeyrunner的截图比较功能就体现出来了.而其他几个流行的框架如Robotium,UIAutomator以及Appium都提供 ...
- 快速构建Windows 8风格应用9-竖直视图
原文:快速构建Windows 8风格应用9-竖直视图 本篇博文主要介绍竖直视图概览.关于竖直视图设计.如何构建竖直视图 竖直视图概览 Windows 8为了支持旋转的设备提供了竖屏视图,我们开发的应用 ...
- PHP中遍历stdclass object 及 json
原文:PHP中遍历stdclass object 及 json (从网上找的模拟实例)需要操作的数据: $test=Array ( [0] => stdClass Object ( [tags] ...
- SQL Server中生成测试数据
原文:SQL Server中生成测试数据 简介 在实际的开发过程中.很多情况下我们都需要在数据库中插入大量测试数据来对程序的功能进行测试.而生成的测试数据往往需要符合特定规则.虽然可以自己写 ...
- ASP.NET抓取网页内容
原文:ASP.NET抓取网页内容 一.ASP.NET 使用HttpWebRequest抓取网页内容 这种方式抓取某些页面会失败 不过,有时候我们会发现,这个程序在抓取某些页面时,是获不到所需的内容的, ...
- ASP.NET DataTable的操作大全
DataTable表示一个与内存有关的数据表,可以使用工具栏里面的控件拖放来创建和使用,也可以在编写程序过程中根据需要独立创建和使用,最常见的情况是作为DataSet的成员使用,在这种情况下就需要用在 ...
- 【工作笔记三】非常全面的讲解Hosts文件
原文:http://www.cnblogs.com/zgx/archive/2009/03/10/1408017.html 很奇怪有很多人不知道Hosts是什么东西.在网络病毒日渐盛行的今天,认识Ho ...