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

标签:C#,Winform,数字,键盘
0
投稿

猜你喜欢

  • SpringBoot项目集成Flyway进行数据库版本控制的详细教程

    2023-11-24 05:20:33
  • Spring Security自定义认证逻辑实例详解

    2023-02-28 19:19:18
  • Java 实战图书管理系统的实现流程

    2023-12-19 05:11:13
  • spring获取bean的源码解析

    2023-10-11 22:15:43
  • intellij idea14打包apk文件和查看sha1值

    2022-05-25 13:18:37
  • winform绑定快捷键的方法

    2023-12-10 22:16:04
  • C#生成EMF矢量图形文件示例详解

    2022-10-30 02:12:56
  • Android开发 旋转屏幕导致Activity重建解决方法

    2022-03-02 06:00:23
  • SpringBoot2使用Jetty容器操作(替换默认Tomcat)

    2023-11-24 01:17:15
  • Android如何让WebView中的HTML5页面实现视频全屏播放

    2023-07-29 00:32:06
  • Java使用ExecutorService来停止线程服务

    2023-01-25 12:10:56
  • 深入浅析Spring 的aop实现原理

    2023-01-10 00:00:10
  • 详解Java中多进程编程的实现

    2021-12-22 01:46:06
  • Idea2020.2创建JavaWeb项目(部署Tomcat)方法详解

    2023-11-02 13:29:52
  • springboot + mybatis + druid + 多数据源的问题详解

    2023-01-24 15:59:58
  • Java 多线程并发LockSupport

    2022-04-07 23:59:57
  • 基于Java实现Actor模型

    2021-12-11 09:28:50
  • Spring的IOC控制反转详解

    2023-08-24 02:50:50
  • C#实现GZip压缩和解压缩入门实例

    2021-05-29 08:20:45
  • Android获取应用版本号与版本名称

    2023-02-09 20:06:11
  • asp之家 软件编程 m.aspxhome.com