C# 经纬度格式化输入控件的简单实现(附html、Qt实现)

一、简述

记--C# 经纬度格式化输入控件的简单实现,方便用户输入。简单实现,待优化。

主要思路是监听用户的每次输入,删除就往光标后补上默认的格式,输入就将光标后面一个字符删除。

例子打包:外链:https://wwa.lanzoui.com/b0c9iuyba 密码:c34t

二、效果

三、工程结构

四、代码

Form1.cs文件

using System;
using System.Windows.Forms;namespace LonLatInput
{public partial class Form1 : Form{public Form1(){InitializeComponent();this.Text = "经纬度格式化输入控件测试";textBoxLon.Text = "123:45:12.98754E";textBoxLon.MaxLength = textBoxLon.Text.Length + 1;textBoxLat.Text = "11:45:12.98754N";textBoxLat.MaxLength = textBoxLon.Text.Length + 1;}private void textBoxLon_TextChanged(object sender, EventArgs e){TextBox textbox = (TextBox)(sender);if (0 >= textbox.Text.Length || textbox.Text.Equals("")){textbox.Text = LonLatTools.LON_FORMAT;return;}int start_index = textbox.SelectionStart;textbox.Text = LonLatTools.FormatLon(textbox.Text, ref start_index);textbox.SelectionStart = start_index;}private void textBoxLat_TextChanged(object sender, EventArgs e){TextBox textbox = (TextBox)(sender);if (0 >= textbox.Text.Length || textbox.Text.Equals("")){textbox.Text = LonLatTools.LAT_FORMAT;return;}int start_index = textbox.SelectionStart;textbox.Text = LonLatTools.FormatLat(textbox.Text, ref start_index);textbox.SelectionStart = start_index;}}
}

LonLatFormat.cs文件

using System;namespace LonLatInput
{enum eType{Longitude = 0,Latitude = 1};class LonLatTools{public const string LON_FORMAT = "000:00:00.00000E";public const string LAT_FORMAT = "00:00:00.00000N";/// <summary>/// 判断是否是0-9数字/// </summary>/// <param name="num"></param>/// <returns></returns>public static bool IsANumber(char num){if ('0' <= num && '9' >= num){return true;}return false;}/// <summary>/// 检查经纬度范围/// </summary>/// <param name="lonlat"></param>/// <param name="type"></param>/// <returns></returns>public static bool CheckLonLat(string lonlat, eType type){if (null == lonlat){return false;}string[] str_arr = lonlat.Split(new char[] { ':', '.', 'E', 'e', 'W', 'w', 'N', 'n', 'S', 's' });if (4 > str_arr.Length){return false;}double dd = Convert.ToDouble(str_arr[0]);double mm = Convert.ToDouble(str_arr[1]);double ss = Convert.ToDouble(str_arr[2]);double sssss = Convert.ToDouble(str_arr[3]);double degree = (dd * 60 * 60 + mm * 60 + ss) * 10000 + sssss;if (eType.Longitude == type){if (degree > (180.0 * 60 * 60 * 10000)){return false;}}else{if (degree > (90.0 * 60 * 60 * 10000)){return false;}}return true;}/// <summary>/// 格式化经度/// </summary>/// <param name="lon"></param>/// <param name="start_index"></param>/// <returns></returns>public static string FormatLon(string lon, ref int start_index){if (0 >= lon.Length || lon.Equals("")){start_index = lon.Length - 1;return LON_FORMAT;}else if (lon.Length > LON_FORMAT.Length){int index = start_index - 1;//输入:将光标后面的字符删除char add_ch = lon[index];char old_ch = '0';//超限后用来恢复原来的值,表现出用户不能输入超限值lon = lon.Remove(index, 1);//先将输入的字符删除,再执行替换操作char[] value_arr = lon.ToCharArray();bool is_change = false;switch (index){//数字类直接替换case 0:case 1:case 2:case 5:case 8:case 10:case 11:case 12:case 13:case 14:if (IsANumber(add_ch)){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 4:case 7://0-5if ('0' <= add_ch && '5' >= add_ch){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 3:case 6:if (':' == add_ch){value_arr[index] = add_ch;is_change = true;}else if ('0' <= add_ch && '5' >= add_ch){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 9:if ('.' == add_ch){value_arr[index] = add_ch;is_change = true;}else if (IsANumber(add_ch)){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 15:if (0 > "[EeWw]".IndexOf(add_ch)){//经纬度需以EeWw结尾value_arr[index] = 'E';}else{value_arr[index] = add_ch;}is_change = true;break;}string new_value = new string(value_arr);//输入无效将光标回退if (!is_change){start_index--;}else{//判断范围是否合法,超限就撤回                    if (!CheckLonLat(new_value, eType.Longitude)){value_arr[index] = old_ch;new_value = new string(value_arr);start_index--;}}lon = new_value;}else if (lon.Length < LON_FORMAT.Length){//删除:在光标后面补默认值lon = lon.Substring(0, start_index)+ LON_FORMAT.Substring(start_index, (LON_FORMAT.Length - lon.Length))+ lon.Substring(start_index);}return lon;}/// <summary>/// 格式化纬度/// </summary>/// <param name="lat"></param>/// <param name="start_index"></param>/// <returns></returns>public static string FormatLat(string lat, ref int start_index){if (0 >= lat.Length || lat.Equals("")){start_index = lat.Length - 1;return LAT_FORMAT;}else if (lat.Length > LAT_FORMAT.Length){int index = start_index - 1;//输入:将光标后面的字符删除char add_ch = lat[index];char old_ch = '0';//超限后用来恢复原来的值,表现出用户不能输入超限值lat = lat.Remove(index, 1);//先将输入的字符删除,再执行替换操作char[] value_arr = lat.ToCharArray();bool is_change = false;switch (index){//数字类直接替换case 0:case 1:case 4:case 7:case 9:case 10:case 11:case 12:case 13:if (IsANumber(add_ch)){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 3:case 6://0-5if ('0' <= add_ch && '5' >= add_ch){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 2:case 5:if (':' == add_ch){value_arr[index] = add_ch;is_change = true;}else if ('0' <= add_ch && '5' >= add_ch){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 8:if ('.' == add_ch){value_arr[index] = add_ch;is_change = true;}else if (IsANumber(add_ch)){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 14:if (0 > "[NnSs]".IndexOf(add_ch)){//经纬度需以EeWw结尾value_arr[index] = 'N';}else{value_arr[index] = add_ch;}is_change = true;break;}string new_value = new string(value_arr);//输入无效将光标回退if (!is_change){start_index--;}else{//判断范围是否合法,超限就撤回                    if (!CheckLonLat(new_value, eType.Latitude)){value_arr[index] = old_ch;new_value = new string(value_arr);start_index--;}}lat = new_value;}else if (lat.Length < LAT_FORMAT.Length){//删除:在光标后面补默认值lat = lat.Substring(0, start_index)+ LAT_FORMAT.Substring(start_index, (LAT_FORMAT.Length - lat.Length))+ lat.Substring(start_index);}return lat;}}
}

五、总结

1、待考虑选中字符输入的情况,粘贴情况。

2、简单实现,待优化。

六、附加

1、html实现

测试代码:

<!DOCTYPE html>
<html><head><title>经纬度格式化输入控件测试</title></head><body>经度: <input type="text" id="lon_id" placeholder="000:00:00.00000E" value="000:00:00.00000E" maxlength="17" oninput="FormatLongitude('lon_id')"/></br>纬度: <input type="text" id="lat_id" placeholder="00:00:00.00000N" value="00:00:00.00000N" maxlength="16" oninput="FormatLatitude('lat_id')"/><script>function IsANumber(num) { /* 判断num是不是0~9之间的数字 */if (undefined == num || null == num || "" == num) {return false;}if (0 <= num && 9 >= num) {return true;}return false;}function CheckLonLat(lonlat, type) {var str_arr = lonlat.split(/[:.]/);if (4 > str_arr.length) {return false;}var dd = parseFloat(str_arr[0]);var mm = parseFloat(str_arr[1]);var ss = parseFloat(str_arr[2]);var sssss = parseFloat(str_arr[3]);var degree = (dd * 60 * 60 + mm * 60 + ss) *10000 + sssss;if ("lon" == type) {if (degree > (180.0 * 60 * 60 * 10000)){return false;}} else {if (degree > (90.0 * 60 * 60 * 10000)){return false;}}return true;}function FormatLongitude(id) {var format = "000:00:00.00000E";var input_obj = document.getElementById(id);var value = input_obj.value;var start_index = input_obj.selectionStart;if (0 >= value.length) { /* 为空就默认为初始状态 */value = format;} else if (value.length > format.length) {  /* 输入:将光标后面一个字符删除 */var index = start_index - 1;var add_ch = value.charAt(index);var value_arr = value.split(""); /*字符串转数组*/value_arr.splice(index, 1);/* 将新添加的字符去掉,后面使用add_ch替换光标后的字符*/var is_change = false;switch (index){//数字类直接替换case 0:case 1:case 2:                                            case 5:                    case 8:case 10:case 11:case 12:case 13:case 14:if (IsANumber(add_ch)){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}                        break;case 4:case 7://0-5if ('0' <= add_ch && '5' >= add_ch){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 3:case 6:if (':' == add_ch){value_arr[index] = add_ch;is_change = true;}else if ('0' <= add_ch && '5' >= add_ch){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 9:if ('.' == add_ch){value_arr[index] = add_ch;is_change = true;}else if (IsANumber(add_ch)){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 15:if (0 > "EeWw".indexOf(add_ch)) {//经纬度需以EeWw结尾value_arr[index] = 'E';}else{                           value_arr[index] = add_ch;}is_change = true;break;}value = value_arr.join("");/*新字符串拼接*///输入无效将光标回退if (!is_change) {start_index--;} else {//判断范围是否合法,超限就撤回                    if (!CheckLonLat(value, "lon")){value_arr[index] = old_ch;value = value_arr.join("");/*新字符串拼接*/start_index--;}}                    } else if (value.length < format.length) { /* 删除:在光标补上默认值 */value = value.substring(0, start_index) + format.substr(start_index, format.length-value.length) + value.substring(start_index);                   }input_obj.value = value;  /*设置新值*/input_obj.setSelectionRange(start_index, start_index);/*设置光标位置*/return value;}function FormatLatitude(id) {var format = "00:00:00.00000N";var input_obj = document.getElementById(id);var value = input_obj.value;var start_index = input_obj.selectionStart;if (0 >= value.length) { /* 为空就默认为初始状态 */value = format;} else if (value.length > format.length) {   /* 输入:将光标后面一个字符删除 */var index = start_index - 1;var add_ch = value.charAt(index);var value_arr = value.split(""); /*字符串转数组*/value_arr.splice(index, 1);/* 将新添加的字符去掉,后面使用add_ch替换光标后的字符*/var is_change = false;switch (index){//数字类直接替换case 0:case 1:case 4:case 7:case 9:case 10:case 11:case 12:case 13:if (IsANumber(add_ch)){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 3:case 6://0-5if ('0' <= add_ch && '5' >= add_ch){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 2:case 5:if (':' == add_ch){value_arr[index] = add_ch;is_change = true;}else if ('0' <= add_ch && '5' >= add_ch){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 8:if ('.' == add_ch){value_arr[index] = add_ch;is_change = true;}else if (IsANumber(add_ch)){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 14:if (0 > "[NnSs]".indexOf(add_ch)){//经纬度需以EeWw结尾value_arr[index] = 'N';}else{value_arr[index] = add_ch;}is_change = true;break;}value = value_arr.join("");/*新字符串拼接*///输入无效将光标回退if (!is_change) {start_index--;} else {//判断范围是否合法,超限就撤回                    if (!CheckLonLat(value, "lat")){value_arr[index] = old_ch;value = value_arr.join("");/*新字符串拼接*/start_index--;}}                  } else if (value.length < format.length) { /* 删除:在光标补上默认值 */value = value.substring(0, start_index) + format.substr(start_index, format.length-value.length) + value.substring(start_index);                   }input_obj.value = value;  /*设置新值*/input_obj.setSelectionRange(start_index, start_index);/*设置光标位置*/return value;}</script></body>
</html>

2、Qt实现

测试主要代码:lonlathelper.cpp

#include "lonlathelper.h"bool IsANumber(char num)
{if ('0' <= num && '9' >= num) {return true;}return false;
}bool CheckLonLat(QString lonlat, eType type)
{QStringList str_arr = lonlat.split(QRegExp("[:.]"));if (4 > str_arr.count()) {return false;}double dd = str_arr[0].toDouble();double mm = str_arr[1].toDouble();double ss = str_arr[2].toDouble();double sssss = str_arr[3].toDouble();double degree = (dd * 60 * 60 + mm * 60 + ss) *10000 + sssss;if (Longitude == type) {if (degree > (180.0 * 60 * 60 * 10000)){return false;}} else {if (degree > (90.0 * 60 * 60 * 10000)){return false;}}return true;
}LonLatHelper::LonLatHelper()
{}QString LonLatHelper::FormatLon(QString lon, int &start_index)
{if (0 >= lon.length()){start_index = lon.length() - 1;return QString(LON_FORMAT);}else if (lon.length() > (int)strlen(LON_FORMAT)){int index = start_index - 1;//输入:将光标后面的字符删除char add_ch = lon.at(index).toLatin1();char old_ch = '0';//超限后用来恢复原来的值,表现出用户不能输入超限值lon = lon.remove(index, 1);//先将输入的字符删除,再执行替换操作QByteArray value_arr = lon.toLocal8Bit();bool is_change = false;switch (index){//数字类直接替换case 0:case 1:case 2:case 5:case 8:case 10:case 11:case 12:case 13:case 14:if (IsANumber(add_ch)){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 4:case 7://0-5if ('0' <= add_ch && '5' >= add_ch){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 3:case 6:if (':' == add_ch){value_arr[index] = add_ch;is_change = true;}else if ('0' <= add_ch && '5' >= add_ch){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 9:if ('.' == add_ch){value_arr[index] = add_ch;is_change = true;}else if (IsANumber(add_ch)){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 15:if (0 > QString("[EeWw]").indexOf(add_ch)){//经纬度需以EeWw结尾value_arr[index] = 'E';}else{value_arr[index] = add_ch;}is_change = true;break;}QString new_value = QString(value_arr);//输入无效将光标回退if (!is_change){start_index--;}else{//判断范围是否合法,超限就撤回if (!CheckLonLat(new_value, Longitude)){value_arr[index] = old_ch;new_value = QString(value_arr);start_index--;}}lon = new_value;}else if (lon.length() < (int)strlen(LON_FORMAT)){//删除:在光标后面补默认值lon = lon.left(start_index)+ QString(LON_FORMAT).mid(start_index, (strlen(LON_FORMAT) - lon.length()))+ lon.right(lon.length()-start_index);}return lon;
}QString LonLatHelper::FormatLat(QString lat, int &start_index)
{if (0 >= lat.length()){start_index = lat.length() - 1;return QString(LAT_FORMAT);}else if (lat.length() > (int)strlen(LAT_FORMAT)){int index = start_index - 1;//输入:将光标后面的字符删除char add_ch = lat.at(index).toLatin1();char old_ch = '0';//超限后用来恢复原来的值,表现出用户不能输入超限值lat = lat.remove(index, 1);//先将输入的字符删除,再执行替换操作QByteArray value_arr = lat.toLocal8Bit();bool is_change = false;switch (index){//数字类直接替换case 0:case 1:case 4:case 7:case 9:case 10:case 11:case 12:case 13:if (IsANumber(add_ch)){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 3:case 6://0-5if ('0' <= add_ch && '5' >= add_ch){old_ch = value_arr[index];value_arr[index] = add_ch;is_change = true;}break;case 2:case 5:if (':' == add_ch){value_arr[index] = add_ch;is_change = true;}else if ('0' <= add_ch && '5' >= add_ch){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 8:if ('.' == add_ch){value_arr[index] = add_ch;is_change = true;}else if (IsANumber(add_ch)){index++;old_ch = value_arr[index];value_arr[index] = add_ch;start_index++;is_change = true;}break;case 14:if (0 > QString("[NnSs]").indexOf(add_ch)){//经纬度需以EeWw结尾value_arr[index] = 'N';}else{value_arr[index] = add_ch;}is_change = true;break;}QString new_value = QString(value_arr);//输入无效将光标回退,表现出来就是非法字符不能输入if (!is_change){start_index--;}else{//判断范围是否合法,超限就撤回,表现出来就是超限不能输入if (!CheckLonLat(new_value, Latitude)){value_arr[index] = old_ch;new_value = QString(value_arr);start_index--;}}lat = new_value;}else if (lat.length() < (int)strlen(LAT_FORMAT)){//删除:在光标后面补默认值lat = lat.left(start_index)+ QString(LAT_FORMAT).mid(start_index, (strlen(LAT_FORMAT) - lat.length()))+ lat.right(lat.length()-start_index);}return lat;
}

C# 经纬度格式化输入控件的简单实现(附html、Qt实现)相关推荐

  1. 【antd】输入控件的思想

    antd对于form中输入控件的抽象十分简单,只要能接收value和onChange属性的组件都可以成为Form.Item的子组件,为Form对应的字段提供值.对于输入控件的抽象我认为这已经达到了极致 ...

  2. 给大家介绍一个日期输入控件javascript实现,我修改了下,符合我的习惯了,^_^!...

    最终效果如图: <formname="form1"method="post"action=""> <p> <i ...

  3. 自定义验证码输入控件

    控件代码深度参考了掘金文章 Android仿滴滴出行验证码输入框效果,增加了 setText() 方法 控件采用多个横向排列的 EditText 组合控件来实现验证码录入框. 自定义属性文件 attr ...

  4. Android动态加载XML文件及控件来简单实现QQ好友印象的功能

    在android开发中,我们常常会遇到界面布局控件不确定的情况.由于某些功能的原因或者为了体现某些app的特色等这些原因会导致我们在实现界面布局时需要动态去加载一些控件,那么下面就来介绍一下如何用动态 ...

  5. PyQt5 基本语法(四):输入控件

    文章目录 2. 输入控件(一) 2.1 纯键盘 2.1.1 QLineEdit 2.1.1.1 描述 2.1.1.2 控件创建 2.1.1.3 输出模式 2.1.1.4 提示字符串 2.1.1.5 清 ...

  6. INFO:InstallShield InstallScript工程中自定义界面文本输入控件的两个注意事项

    在使用InstallScript工程增加自定义界面过程中,我用到了文本输入控件(Edit Field),用于用户名和密码的输入. 首先是用户名,如果用户名长度超过我的控件长度时,发现无法再继续输入内容 ...

  7. WPF IP地址输入控件的实现

    WPF IP地址输入控件的实现 原文:WPF IP地址输入控件的实现 一.前言 WPF没有内置IP地址输入控件,因此我们需要通过自己定义实现. 我们先看一下IP地址输入控件有什么特性: 输满三个数字焦 ...

  8. 正则表达式——WPF输入控件TextBox 限定输入特定字符

    正则表达式--WPF输入控件TextBox 限定输入特定字符 原文:正则表达式--WPF输入控件TextBox 限定输入特定字符 概念: 正则表达式是对字符串操作的一种逻辑公式, 就是用事先定义好的一 ...

  9. android 日程安排view,RecyclerView 列表控件中简单实现时间线

    时间 时间,时间,时间啊:走慢一点吧- 看见很多软件中都有时间线的东西,貌似天气啊,旅游啊什么的最多了:具体实现方式很多,在本篇文章中讲解一种自定义View封装的方式. 效果 先来看看效果. 分析 软 ...

  10. jquery-文档操作-标签取值-输入控件取值与赋值

    html 文本 值 获取标签包裹的内容 dom的属性 jquery的方法 演练 小结 dom对象,jquery对象,取值方式的对等 对象 纯文本 html文本 dom innerText innerH ...

最新文章

  1. 【深度学习】强化学习Q-Learning和DQN的应用(迷宫)
  2. 有必要学python吗-让孩子学Python编程有必要吗
  3. hdu1285 拓扑序
  4. 计算机本地用户删除后怎么恢复,电脑本地磁盘盘符被隐藏C盘不见了恢复方法...
  5. 如何应对互联网界的奇葩面试题!
  6. 【java】java 并发编程 LinkedBlockingDeque
  7. matlab版VLFeat安装
  8. python输入逗号分隔_Python实现按逗号分隔列表的方法
  9. 使用 jsonp解决跨域问题,在vue中成功调用心知天气api
  10. 微信小程序链接wifi
  11. 系统重装计算机硬件不兼容,升级Win10系统出现兼容性报告详细解答
  12. 启动项目,报错:The server selected protocol version TLS10 is not accepted by client preferences [TLS12]解决办法
  13. NB-IoT和eMTC对比
  14. 从 RHEL 6 升级至 RHEL 7
  15. 三角形的测试用例设计案例
  16. k8s中将flannel网络切换calico网络
  17. python 匹配段落_段落匹配Python
  18. 硬盘 U盘 的SN 号码 javascript 读取 PID,VID,SN信息
  19. TCP 协议如何保证可靠传输?
  20. 川崎机器人几百个示教点位置的动态修正

热门文章

  1. pdsh@xxxx: localhost: connect: Connection refused
  2. python卡方检验计算pvalue值_Python数据科学:卡方检验
  3. el-menu菜单下划线解决办法
  4. 阿里云对象存储OSS服务——上传/删除/获取图片
  5. 计算机控制键有哪些,常用的电脑快捷键大全有哪些
  6. 云展网教程 | 如何更改logo和设置点击logo时的转跳链接?
  7. NYOJ54-小明的存钱计划
  8. java毕业设计蛋糕店会员系统Mybatis+系统+数据库+调试部署
  9. 语音识别—声学模型训练(前向-后向算法)
  10. 二叉树多种遍历的时间复杂度和空间复杂度