分享
 
 
 

一个只允许输入数字值的文本框,并且带有输入范围设置功能。

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

自认为注释比较详细了,所以就不作介绍了.

我也没有搜索其他类似的控件来进行比较,可能其他控件更好,仅作一起学习吧。

如有错误或其他更好的控件,请留言。

using System;

using System.Drawing;

using System.Windows.Forms;

namespace MyLibrary.Controls

{

/// <summary>

/// 一个只允许输入数字值的文本框,并且带有输入范围设置功能。

/// </summary>

public class NumericTextBox : System.Windows.Forms.TextBox

{

[System.Runtime.InteropServices.DllImport("user32.dll")]

private static extern bool MessageBeep(uint beep);

private int minimum = 0;

private int maximum = 100;

private bool useRange = false;

private string lastChar;

public NumericTextBox()

{

base.Text = "0";

}

/// <summary>

/// 获取或设置可以接受的数据集范围

/// 如果设置的最大值大于等于设置的最小值,

/// 则表示允许的值在这两个设置值之间。

/// 如果设置的最大值小于设置的最小值,

/// 则表示允许的值在这两个设置值之外。

/// </summary>

public Size SetRange

{

get

{

return new Size(minimum, maximum);

}

set

{

if (this.SetRange == value)

return;

minimum = value.Width;

maximum = value.Height;

// 空文本的数值范围验证

if (this.useRange && base.Text == "")

{

base.Text = GetMinimumText();

return;

}

this.ValidateText();

}

}

// 以下两个辅助方法是 VS.NET 设计器所需的。

public bool ShouldSerializeSetRange(){ return (new Size(0, 100) != this.SetRange); }

public void ResetSetRange() { this.maximum = 100; this.minimum = 0; }

/// <summary>

/// 获取或设置是否要使用限定值的范围

/// </summary>

[System.ComponentModel.DefaultValue(false)]

public bool UseRange

{

get

{

return this.useRange;

}

set

{

if (this.useRange == value)

return;

this.useRange = value;

// 空文本的数值范围验证

if (this.useRange && base.Text == "")

{

base.Text = GetMinimumText();

return;

}

this.ValidateText();

}

}

/// <summary>

/// 为了检查程序设置的文本值有效性,所以隐藏了基类的 Text 属性。

/// </summary>

[System.ComponentModel.DefaultValue("0")]

public new string Text

{

get

{

return base.Text;

}

set

{

// 检查是否是一个数字

try

{

Double.Parse(value);

}

catch

{

// 空文本的数值范围验证

if (this.useRange && base.Text == "")

{

base.Text = GetMinimumText();

}

return;

}

base.Text = value;

this.ValidateText();

}

}

/// <summary>

/// 复盖基类的 OnKeyPress 方法

/// 用以检测按键是否符合要求。

/// </summary>

/// <param name="e"></param>

protected override void OnKeyPress(KeyPressEventArgs e)

{

// 回车符,检查文本数字值的有效性

if (e.KeyChar == 13)

{

this.ValidateText();

// 注意,此处要先检查后再调用基类方法

// 因为基类方法引发的事件处理回调中需要使用到控件的值。

// 为了回调能够得到准确的值,所以要先进行检查处理。

base.OnKeyPress(e);

return;

}

// 调用基类方法。先由基类来处理此次按键事件。

base.OnKeyPress(e);

// 如果基类的调用已处理了此键,直接返回吧。

if (e.Handled)

return;

// 如果是 - 或 +,只能在第一个位置输入,且不能重复输入。

if ( e.KeyChar == '-' || e.KeyChar == '+')

{

if (base.Text.StartsWith("-") ||

base.Text.StartsWith("+") ||

base.SelectionStart != 0) // 检测光标是否在第一个位置上

e.Handled = true;

}

else if ( e.KeyChar == '.' ) // 小数点最多只能输入一个。

{

e.Handled = (base.Text.IndexOf('.') >= 0);

}

else

{

// 其他情况只能是数字字符和后退符。

// 可自行修改补充,以适合更广泛的要求。

e.Handled = !(Char.IsDigit(e.KeyChar) || e.KeyChar == 8);

}

// 如果是不合要求的字符,则发出一个警告音。

if (e.Handled)

MessageBeep(0x00000030);

}

/// <summary>

/// 复盖基类的 OnValidated 方法

/// 用以检测文本是否符合范围要求。

/// </summary>

/// <param name="e"></param>

protected override void OnValidated(EventArgs e)

{

base.OnValidated(e);

this.ValidateText();

}

/// <summary>

/// 当非空文本时,验证文本的数值范围。

/// </summary>

protected virtual void ValidateText()

{

// 如果没有使用范围验证,直接返回

if (this.useRange == false)

return;

// 如果文本为空、-、+,不在此作任何验证。

if (this.IsEmpty())

return;

decimal val = 0;

bool normal = true;

try

{

val = Convert.ToDecimal(base.Text);

}

catch

{

normal = false;

}

// 如果解析正常

if (normal)

{

// 如果设置的最大值大于等于设置的最小值,

// 则表示允许的值在这两个设置值之间。

if (maximum >= minimum)

{

if ( val > maximum )

{

base.Text = maximum.ToString();

}

else if ( val < minimum )

{

base.Text = minimum.ToString();

}

}

// 如果设置的最大值小于设置的最小值,

// 则表示允许的值在这两个设置值之外。

else

{

if ( val < minimum && val > maximum )

{

base.Text = maximum.ToString();

// 也可使用以下方法,结果相同。

// base.Text = GetMinimumText();

}

}

}

else

{

// 如有异常,则使用设置的最小值。

base.Text = GetMinimumText();

}

// 如果除了 - 和 + 以外的文本长度为 1,记住它。

// 因为用户可能会在删除了最后一个字符后,将输入焦点转移到其他控件。

// 这么做是为了能在失去焦点时保持文本框不为空。

// 有关操作,请见 OnLostFocus。

if ( base.Text.StartsWith( "-" ) || base.Text.StartsWith( "+" ))

{

if ( base.Text.Length == 2)

{

lastChar = base.Text;

}

}

else

{

if ( base.Text.Length == 1)

{

lastChar = base.Text;

}

}

}

protected override void OnLostFocus(EventArgs e)

{

base.OnLostFocus(e);

// 当用户的输入焦点离开了此文本框时,

// 并且当设定了数值的范围,并且文本的宽度为 0 时,

// 将以前记住的最后有效字符串重新填充。

// 因为设置了范围后,就不能让文本框中为空。

if ( this.IsEmpty() && useRange )

{

if (lastChar != null)

base.Text = lastChar;

else

base.Text = GetMinimumText();

}

}

protected string GetMinimumText()

{

if (maximum >= minimum)

{

return minimum.ToString();

}

else

{

return maximum.ToString();

}

}

protected bool IsEmpty()

{

return (base.Text == "" || base.Text == "-" || base.Text == "+");

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有