C#實(shí)現(xiàn)Winform小數(shù)字鍵盤模擬器
文章開始之前,先看一下效果圖,看是不是您正所需要的:

一、構(gòu)建計(jì)算器的界面
要構(gòu)建出一個(gè)好看點(diǎn)的計(jì)算器界面,還是需要頗費(fèi)些小心思的,我做這個(gè)的時(shí)候,也花了兩三個(gè)小時(shí)的時(shí)間構(gòu)建這個(gè)界面。
其主要的使用控制是TableLayoutPanel控件。
另外一個(gè)小難點(diǎn)則在于內(nèi)容控件Textbox的顯示,要讓文字垂直居中,在沒有重寫Textbox控件的情況下要達(dá)到這個(gè)效果,也是花了些小心思。
其它的界面則沒有什么的。至于加減號(hào)嘛,則用輸入法的特殊符號(hào)即可。
二、構(gòu)建控件的開放屬性
一共開放了3個(gè)屬性,不夠自己加。這3個(gè)如下,看注釋應(yīng)該能懂:
/// <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>
/// 設(shè)置小數(shù)點(diǎn)的精度位數(shù),默認(rèn)為2位小數(shù)點(diǎn)
/// </summary>
[Browsable(true)]
[Category("Zhongzhou")]
[DefaultValue(2)]
[Description("設(shè)置小數(shù)點(diǎn)的精度位數(shù),默認(rèn)為2位小數(shù)點(diǎn)")]
public int Precision { get; set; } = 2;
三、控件鍵盤輸入
我們的目的是讓小鍵盤來(lái)輸入數(shù)字,所以需要禁止實(shí)體鍵盤輸入文字字母等信息,以及小數(shù)字點(diǎn)最多只能出現(xiàn)一次,具體邏輯如下:
/// <summary>
/// 當(dāng)使用實(shí)物鍵盤輸入文本內(nèi)容時(shí)觸發(fā)
/// </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代表小數(shù)點(diǎn)
if ((e.KeyChar < 48 || e.KeyChar >= 57) && (e.KeyChar != 8) && (e.KeyChar != 46))
{
e.Handled = true;
return;
}
//判斷多次輸入小數(shù)點(diǎn),僅允許出現(xiàn)1次小數(shù)點(diǎn)
if (e.KeyChar == 46)
{
this.PointHandle();
this.SetContentFocus();
e.Handled = true;
return;
}
}
/// <summary>
/// 處理小數(shù)點(diǎn)
/// </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;
}
//取光標(biāo)位置
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)));
}
四、讓文本框處理焦點(diǎn)狀態(tài)以及光標(biāo)位置的處理
光標(biāo)位置,需要特殊處理的,默認(rèn)參數(shù)cursorPosition=-1時(shí),光標(biāo)位置始終移到最末尾處。但是有些情況,比如你要讓光標(biāo)在數(shù)字中間刪除幾個(gè)數(shù)字或者添加幾個(gè)數(shù)字,就不能讓光標(biāo)自動(dòng)跑到最末尾處了。
/// <summary>
/// 設(shè)置新值
/// </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;
}
五、實(shí)現(xiàn)退格、清除內(nèi)容的功能
/// <summary>
/// 清除內(nèi)容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ClearButton_Click(object sender, EventArgs e)
{
this.SetContent(string.Empty);
this.SetContentFocus();
}
/// <summary>
/// 退格內(nèi)容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BackButton_Click(object sender, EventArgs e)
{
//取光標(biāo)位置
int index = this.ContentTextBox.SelectionStart;
//剪切內(nèi)容
string cutStr = this.ContentTextBox.Text.Substring(0, index);
//剩余內(nèi)容
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);
}
六、實(shí)現(xiàn)Enter確認(rèn)得到結(jié)果的功能
原理是通過(guò)事件來(lái)實(shí)現(xiàn)的。代碼如下:
/// <summary>
/// 當(dāng)按下回車按鈕時(shí)的事件委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void EnteredEventHandler(object sender, float e);
/// <summary>
/// 當(dāng)按下回車按鈕時(shí)的事件
/// </summary>
public event EnteredEventHandler Entered;
/// <summary>
/// 當(dāng)迷你小鍵盤按下回車時(shí)觸發(fā)事件
/// </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("值不在最大范圍內(nèi)", "提示");
return;
}
if (min != 0 && value < min)
{
MessageBox.Show("值不在最小范圍內(nèi)", "提示");
return;
}
this.Entered?.Invoke(this, value);
}
/// <inheritdoc cref="OnEntered"/>
private void EnterButton_Click(object sender, EventArgs e)
{
this.OnEntered();
this.SetContentFocus();
}
到此這篇關(guān)于C#實(shí)現(xiàn)Winform小數(shù)字鍵盤模擬器的文章就介紹到這了,更多相關(guān)C# Winform數(shù)字鍵盤模擬器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在C#的類或結(jié)構(gòu)中重寫ToString方法的用法簡(jiǎn)介
這篇文章主要介紹了在C#的類或結(jié)構(gòu)中重寫ToString方法的用法簡(jiǎn)介,需要的朋友可以參考下2016-01-01
互斥量mutex的簡(jiǎn)單使用(實(shí)例講解)
本篇文章主要是對(duì)互斥量mutex的簡(jiǎn)單使用進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01
c#實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能示例分享
這篇文章主要介紹了c#實(shí)現(xiàn)的斷點(diǎn)續(xù)傳功能示例,斷點(diǎn)續(xù)傳就是在上一次下載時(shí)斷開的位置開始繼續(xù)下載。在HTTP協(xié)議中,可以在請(qǐng)求報(bào)文頭中加入Range段,來(lái)表示客戶機(jī)希望從何處繼續(xù)下載,下面是示例,需要的朋友可以參考下2014-03-03
C#校驗(yàn)時(shí)間格式的場(chǎng)景分析
本文通過(guò)場(chǎng)景分析給大家講解C#里如何簡(jiǎn)單的校驗(yàn)時(shí)間格式,本次的場(chǎng)景屬于比較常見的收單API,對(duì)第三方的訂單進(jìn)行簽名驗(yàn)證,然后持久化到數(shù)據(jù)庫(kù),需要的朋友跟隨小編一起看看吧2022-08-08

