C#实现Winform小数字键盘模拟器
作者:中洲少年 发布时间:2021-08-29 12:34:25
标签:C#,Winform,数字,键盘
文章开始之前,先看一下效果图,看是不是您正所需要的:
一、构建计算器的界面
要构建出一个好看点的计算器界面,还是需要颇费些小心思的,我做这个的时候,也花了两三个小时的时间构建这个界面。
其主要的使用控制是TableLayoutPanel控件。
另外一个小难点则在于内容控件Textbox的显示,要让文字垂直居中,在没有重写Textbox控件的情况下要达到这个效果,也是花了些小心思。
其它的界面则没有什么的。至于加减号嘛,则用输入法的特殊符号即可。
二、构建控件的开放属性
一共开放了3个属性,不够自己加。这3个如下,看注释应该能懂:
/// <summary>
/// 可接受的最小值,最小为-3.402823E+38
/// </summary>
[Browsable(true)]
[Category("Zhongzhou")]
[DefaultValue(0)]
[Description("可接受的最小值,最小为-3.402823E+38")]
public float Min { get; set; } = 0;
/// <summary>
/// 可接受的最大值,最大为3.402823E+38
/// </summary>
[Browsable(true)]
[Category("Zhongzhou")]
[DefaultValue(0)]
[Description("可接受的最大值,最大为3.402823E+38")]
public float Max { get; set; } = 0;
/// <summary>
/// 设置小数点的精度位数,默认为2位小数点
/// </summary>
[Browsable(true)]
[Category("Zhongzhou")]
[DefaultValue(2)]
[Description("设置小数点的精度位数,默认为2位小数点")]
public int Precision { get; set; } = 2;
三、控件键盘输入
我们的目的是让小键盘来输入数字,所以需要禁止实体键盘输入文字字母等信息,以及小数字点最多只能出现一次,具体逻辑如下:
/// <summary>
/// 当使用实物键盘输入文本内容时触发
/// </summary>
/// <param name="e"></param>
private void OnKeyPressed(KeyPressEventArgs e)
{
//13表示回车
if (e.KeyChar == 13)
{
this.OnEntered();
e.Handled = true;
return;
}
//48代表0,57代表9,8代表空格,46代表小数点
if ((e.KeyChar < 48 || e.KeyChar >= 57) && (e.KeyChar != 8) && (e.KeyChar != 46))
{
e.Handled = true;
return;
}
//判断多次输入小数点,仅允许出现1次小数点
if (e.KeyChar == 46)
{
this.PointHandle();
this.SetContentFocus();
e.Handled = true;
return;
}
}
/// <summary>
/// 处理小数点
/// </summary>
/// <returns><see langword="true"/>表示处理成功,<see langword="false"/>表示未处理</returns>
private bool PointHandle()
{
string content = this.ContentTextBox.Text;
if (content.IndexOf('.') != -1)
{
return false;
}
if (string.IsNullOrEmpty(content))
{
this.SetContent("0.");
return true;
}
//取光标位置
int index = this.ContentTextBox.SelectionStart;
string str = this.ContentTextBox.Text.Substring(0, index);
if (str == "+" || str == "-")
{
return this.SetContent(string.Join(string.Empty, str, "0.", this.ContentTextBox.Text.Substring(index, this.ContentTextBox.Text.Length - index)));
}
return this.SetContent(string.Join(string.Empty, str, ".", this.ContentTextBox.Text.Substring(index, this.ContentTextBox.Text.Length - index)));
}
四、让文本框处理焦点状态以及光标位置的处理
光标位置,需要特殊处理的,默认参数cursorPosition=-1时,光标位置始终移到最末尾处。但是有些情况,比如你要让光标在数字中间删除几个数字或者添加几个数字,就不能让光标自动跑到最末尾处了。
/// <summary>
/// 设置新值
/// </summary>
/// <param name="newContent">表示新值</param>
private bool SetContent(string newContent)
{
int precision = this.Precision;
if (string.IsNullOrEmpty(newContent))
{
this.ContentTextBox.Text = string.Empty;
return true;
}
var scheme = newContent.Split('.');
if (scheme.Length == 2)
{
var realPrecision = scheme[1].Length;
if (realPrecision > precision)
{
return false;
}
}
this.ContentTextBox.Text = newContent;
return true;
}
五、实现退格、清除内容的功能
/// <summary>
/// 清除内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearButton_Click(object sender, EventArgs e)
{
this.SetContent(string.Empty);
this.SetContentFocus();
}
/// <summary>
/// 退格内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BackButton_Click(object sender, EventArgs e)
{
//取光标位置
int index = this.ContentTextBox.SelectionStart;
//剪切内容
string cutStr = this.ContentTextBox.Text.Substring(0, index);
//剩余内容
string remainStr = this.ContentTextBox.Text.Substring(index, this.ContentTextBox.Text.Length - index);
int position = this.SetContent(string.Join(string.Empty, cutStr.Substring(0, cutStr.Length - 1), remainStr)) ? index - 1 : index;
this.SetContentFocus(position);
}
六、实现Enter确认得到结果的功能
原理是通过事件来实现的。代码如下:
/// <summary>
/// 当按下回车按钮时的事件委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void EnteredEventHandler(object sender, float e);
/// <summary>
/// 当按下回车按钮时的事件
/// </summary>
public event EnteredEventHandler Entered;
/// <summary>
/// 当迷你小键盘按下回车时触发事件
/// </summary>
protected virtual void OnEntered()
{
float min = this.Min;
float max = this.Max;
var value = string.IsNullOrEmpty(this.ContentTextBox.Text) ? 0 : Convert.ToSingle(this.ContentTextBox.Text);
if (max != 0 && value > max)
{
MessageBox.Show("值不在最大范围内", "提示");
return;
}
if (min != 0 && value < min)
{
MessageBox.Show("值不在最小范围内", "提示");
return;
}
this.Entered?.Invoke(this, value);
}
/// <inheritdoc cref="OnEntered"/>
private void EnterButton_Click(object sender, EventArgs e)
{
this.OnEntered();
this.SetContentFocus();
}
来源:https://blog.csdn.net/mazhiyuan1981/article/details/121280371


猜你喜欢
- ModbusModbus是一种串行通信协议。Modbus 一个工业上常用的通讯协议、一种通讯约定。Modbus协议包括RTU、ASCII、T
- 配置宝塔面板javaweb运行环境详解,若出现404nignx错误也可按此教程进行检查1.准备:(解析成功的域名,本地运行完好的项目,宝塔面
- 1、用ASCII码判断在 ASCII码表中,英文的范围是0-127,而汉字则是大于127,具体代码如下:string text = &quo
- 关键词IDEA 如何控制编辑左侧的功能图标 ICONIDEA 左侧的图标不见了怎么恢复1、操作步骤依次打开 File | Settings
- 项目中有这样一个需求,网页上上传了一个视频,需要获取此视频的时长、大小,把这两个数据返回给前
- 本文实例展示了DevExpress实现为TextEdit设置水印文字的方法,是一个很实用的技巧。分享给大家供大家参考。关键代码如下:publ
- 目录阻塞队列简介java中的阻塞队列BlockQueue中方法阻塞队列的实现原理总结阻塞队列简介阻塞队列(BlockingQueue)首先是
- 前言最近在工作中需要编译android下的动态库,本以为是一件简单的事,没想到因为工具,以及google本身被墙的原因,折腾了好久。在win
- Java7中文件IO发生了很大的变化,专门引入了很多新的类:import java.nio.file.DirectoryStream;imp
- 功能实现:1、图片加载类ImageLoader实现:1)用阻塞队列存储要图片:BlockingQueue images = new Arra
- 一、树概念及结构1.1 树的概念树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因 为
- 本文实例讲述了Java泛型的使用限制。分享给大家供大家参考,具体如下:一 什么情况下不能使用泛型1 不能使用泛型的形参创建对象。T o=ne
- Spring Boot 最主要的特性就是AutoConfig(自动配置),而对于我们这些使用者来说也就是各种starter,Spring B
- String boot 部署SpringBoot部署也是非常简单,首先,需要把打包输出的包由jar改为war,即修改pom.xml中pack
- 找到framework/base/core/res/res/values/dimens.xml,在其中把Navigation的配置改成0 &
- 存储过程:CREATE PROCEDURE [dbo].[Proc_GetInfo] @yw
- 本文主要介绍了java中LinkedList使用迭代器优化移除批量元素原理,分享给大家,具体如下:public interface Iter
- 前言对于正则表达式,相信很多人都知道,但是很多人的第一感觉就是难学,因为看第一眼时,觉得完全没有规律可寻,而且全是一堆各种各样的特殊符号,完
- 本文实例总结了C#遍历DataSet控件的方法。分享给大家供大家参考。具体方法如下:DataSet控件在.net主要是用来存储数据的,它更像
- 为什么要使用Lambda?可以对一个接口进行非常简洁的实现。Lambda对接口的要求?接口中定义的抽象方法有且只有一个才可以。传统实现一个接