由于项目需要,最近写了一个数字输入文本框,在此作个备忘。

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的更多相关文章

  1. C#Winform使用扩展方法自定义富文本框(RichTextBox)字体颜色

    在利用C#开发Winform应用程序的时候,我们有可能使用RichTextBox来实现实时显示应用程序日志的功能,日志又分为:一般消息,警告提示 和错误等类别.为了更好地区分不同类型的日志,我们需要使 ...

  2. C# 全选中数字文本框内容

    /// <summary>        /// 全选中数字文本框内容        /// </summary>        /// <param name=&quo ...

  3. [WPF]实现TextBox文本框单击全选

    原文:[WPF]实现TextBox文本框单击全选 /// <summary>         /// Void:设置获取焦点时全选文本         /// </summary&g ...

  4. WPF自定义数字输入框控件

    要求:只能输入数字和小数点,可以设置最大值,最小值,小数点前长度,小数点后长度(支持绑定设置): 代码如下: using System; using System.Collections.Generi ...

  5. [C# WPF] 关于将文本框竖起来(旋转文字)

    xx.xmal.cs 后台代码中动态添加控件到 UI 文字显示在一个 Canvas 中(定位用Canvas.SetLeft() / Canvas.SetTop() ), 为了实现排版效果,可适当在 T ...

  6. WPF 自定义文本框输入法 IME 跟随光标

    本文告诉大家在 WPF 写一个自定义的文本框,如何实现让输入法跟随光标 本文非小白向,本文适合想开发自定义的文本框,从底层开始开发的文本库的伙伴.在开始之前,期望了解了文本库开发的基础知识 本文实现的 ...

  7. [JS] 文本框判断输入的内容是否为数字

    可以通过触发文本框的onchange事件来对输入的内容进行判断是否为数字 文本框的属性设置: 把onchange的属性对应的js函数写好即可 参数传输的是当前控件的value值,即text值 < ...

  8. JS学习笔记 - 自定义右键菜单、文本框只能输入数字

    <script> // 事件总共有2个部分, //1.点击鼠标右键的表现 oncontextmenu 2.点击鼠标左键的表现(即普通点击onclick) // 点击右键,div位置定位到鼠 ...

  9. JavaScript 自定义文本框光标——初级版

    文本框(input或textarea)的光标无法修改样式(除了通过color修改光标颜色).但笔者希望个人创建自己的网站时,文本框的光标有属于自己的风格.所以,尝试模拟文本框的光标,设计有自己风格的光 ...

随机推荐

  1. 快速构建Windows 8风格应用6-GridView数据控件

    原文:快速构建Windows 8风格应用6-GridView数据控件 本篇博文主要介绍什么是GridView数据控件.如何构建常用的GridView数据呈现样式. 什么是GridView数据控件? G ...

  2. C++ Primer 学习笔记_63_重载运算符和转换 --转换和类类型【上】

    重载运算符和转换 --转换与类类型[上] 引言: 在前面我们提到过:能够用一个实參调用的位 unsignedchar 相同范围的值,即:0到255. 这个类能够捕获下溢和上溢错误,因此使用起来比内置u ...

  3. 【转】NuGet的安装与使用

    学习了一段时间的MVC,今天想自己尝试初步搭建一个MVC框架,结果新建MVC4.0(MVC3.0同样)项目时,弹出一个错误提示框,如下图.上网一搜,说是要安装一个第三方组件NuGet.刚接触MVC,更 ...

  4. fscanf功能具体解释

    cfscanf fscanf fscanf : 格,fscanf格格 :int fscanf(FILE *stream, char *format,[argument...]); int fscanf ...

  5. SSMS2008插件开发(1)--介绍

    原文:SSMS2008插件开发(1)--介绍 SSMS2008就是Microsoft Sql Server Management Studio 2008的简称.许多人叫做SQL2008或SQL SER ...

  6. XLSTransformer生成excel一个简单的演示示例文件

    项目结构图: 在这些项目中使用jar.可以http://www.findjar.com/index.x下载 ExcelUtil类源代码: package util; import java.io.IO ...

  7. 在SQL Server中添加Linked Server 图解版

    在开发中,经常需要一个SQL Server服务器去访问另一个服务器,微软提供了一种方式Linked Server 下面是配置流程: 1).打开Server Objects下 Linked Server ...

  8. WebActivator的实现原理详解

    WebActivator的实现原理详解 文章内容 上篇文章,我们分析如何动态注册HttpModule的实现,本篇我们来分析一下通过上篇代码原理实现的WebActivator类库,WebActivato ...

  9. 有关Android存储的相关概念辨析

    我想念许多Android开发人员在碰到有关存储的相关问题时,肯定遇到过“内部存储/内存”.“外部存储/外存”等类似的概念,尤其是将相关概念跟非开发人员解释时,那真是“秀才遇到兵,有理说不清哪”.包括我 ...

  10. 关于模板pair的用法

    在挑战程序设计竞赛中看到调用pair,就上网查了一下 类型申明有两种 template <class T1, class T2> struct pair typedef pairt< ...