C# WinForm移除非法字符的输入框

news2024/12/18 16:37:28

C# WinForm移除非法字符的输入框

文章目录


namespace System.Windows.Forms
{
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;

    /// <summary>
    /// 移除非法字符的服务。
    /// </summary>
    public class TextBoxBaseRemoveCharService
    {
        public TextBoxBaseRemoveCharService(TextBoxBase textBox)
        {
            this.TextBox = textBox;
        }

        #region 初始化函数。

        /// <summary>
        /// 更新 有效字符 为 整数 的字符。
        /// </summary>
        public void UpdateValidCharAsInteger()
        {
            ValidChars = GetIntegerChars();
        }

        /// <summary>
        /// 整数 的 字符。
        /// </summary>
        /// <returns></returns>
        public static IList<char> GetIntegerChars()
        {
            return new char[]
            {
                '0',
                '1',
                '2',
                '3',
                '4',
                '5',
                '6',
                '7',
                '8',
                '9',
            };
        }

        /// <summary>
        /// 更新 无效字符 为 换行 的字符。
        /// </summary>
        public void UpdateInvalidCharAsNewLine()
        {
            InvalidChars = GetNewLineChars();
        }

        /// <summary>
        /// 换行 的字符。
        /// </summary>
        /// <returns></returns>
        public static IList<char> GetNewLineChars()
        {
            return new char[]
            {
                '\v',
                '\r',
                '\n',
            };
        }

        #endregion 初始化函数。

        #region 移除非法字符。

        /// <summary>
        /// 在 调用 <see cref="TextBoxBase.OnTextChanged(EventArgs)"/> 前执行。 <br />
        /// 注意:在重载函数中,调用本函数,本函数所属的对象可能为 null 。
        /// 所以,调用示例为 RemoveCharService?.OnTextChangedBefore()
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("", "S134")]
        public void OnTextChangedBefore()
        {
            var safeValidChars = ValidChars;
            var hasValidChars = safeValidChars != null && safeValidChars.Count > 0;
            var safeInvalidChars = InvalidChars;
            var hasInvalidChars = safeInvalidChars != null && safeInvalidChars.Count > 0;
            if (DisabledRemoveInvalidChars || (!hasValidChars && !hasInvalidChars))
            {
                return;
            }

            string oldText = TextBox.Text;
            if (string.IsNullOrEmpty(oldText))
            {
                return;
            }

            StringBuilder newBuilder = new StringBuilder(oldText.Length);
            List<int> removeIndexes = new List<int>(16);
            int index = -1;
            foreach (var ch in oldText)
            {
                ++index;
                if (hasValidChars)
                {
                    if (!safeValidChars.Contains(ch))
                    {
                        removeIndexes.Add(index);
                    }
                    else
                    {
                        newBuilder.Append(ch);
                    }
                }
                // 等价 else if (hasInvalidChars)
                else
                {
                    if (safeInvalidChars.Contains(ch))
                    {
                        removeIndexes.Add(index);
                    }
                    else
                    {
                        newBuilder.Append(ch);
                    }
                }
            }
            OnTextChangedBeforeCore(oldText, newBuilder, removeIndexes);
        }

        private void OnTextChangedBeforeCore(string oldText, StringBuilder newBuilder, List<int> removeIndexes)
        {
            string newText = newBuilder.ToString();
            if (newText != oldText)
            {
                TextBox.SuspendLayout();
                try
                {
                    // 处理重命名时,当输入非法字符时,会全选名称的问题。
                    int selectionStartOld = 0;
                    int selectionLengthOld = 0;
                    var isReadySelection = !string.IsNullOrEmpty(newText) &&
                        ReadySelect(out selectionStartOld, out selectionLengthOld);

                    TextBox.Text = newText;

                    // 处理重命名时,当输入非法字符时,会全选名称的问题。
                    if (isReadySelection)
                    {
                        selectionLengthOld -= MatchIndexCount(removeIndexes, selectionStartOld - 1, selectionStartOld + selectionLengthOld);
                        selectionStartOld -= MatchIndexCount(removeIndexes, -1, selectionStartOld);
                        GetSafeSelect(newText.Length, ref selectionStartOld, ref selectionLengthOld);
                        UpdateSelect(selectionStartOld, selectionLengthOld);
                    }
                }
                finally
                {
                    TextBox.ResumeLayout();
                }
            }
        }

        private int MatchIndexCount(IList<int> indexList, int minIndex, int maxIndex)
        {
            int count = 0;
            foreach (var index in indexList)
            {
                if (index > minIndex && index < maxIndex)
                {
                    ++count;
                }
            }
            return count;
        }

        private bool ReadySelect(out int selectionStart, out int selectionLength)
        {
            bool isSuccessCompleted;
            try
            {
                selectionStart = TextBox.SelectionStart;
                selectionLength = TextBox.SelectionLength;
                isSuccessCompleted = true;
            }
            catch (Exception ex)
            {
                TraceException("Ready selection exception: ", ex);
                selectionStart = 0;
                selectionLength = 0;
                isSuccessCompleted = false;
            }
            return isSuccessCompleted;
        }

        private void UpdateSelect(int selectionStart, int selectionLength)
        {
            try
            {
                TextBox.Select(selectionStart, selectionLength);
            }
            catch (Exception ex)
            {
                TraceException("Update selection exception: ", ex);
            }
        }

        private void GetSafeSelect(int length, ref int selectionStart, ref int selectionLength)
        {
            if (selectionStart > length)
            {
                selectionStart = length;
            }

            if (selectionLength > length)
            {
                selectionLength = length;
            }
        }

        #endregion 移除非法字符。

        private static void TraceException(string message, Exception ex)
        {
            System.Diagnostics.Trace.WriteLineIf(true, message + ex);
        }

        /// <summary>
        /// 禁止移除非法字符。
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DefaultValue(false)]
        public bool DisabledRemoveInvalidChars { get; set; }

        /// <summary>
        /// 有效字符。 <br />
        /// 注意:<see cref="ValidChars"/> 和 <see cref="InvalidChars"/> 最多一个不为 null 。
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DefaultValue(null)]
        private IList<char> ValidChars
        {
            get { return validChars; }
            set
            {
                if (validChars != value)
                {
                    if (value != null)
                    {
                        InvalidChars = null;
                    }
                    validChars = value;
                }
            }
        }

        private IList<char> validChars;

        /// <summary>
        /// 无效字符。 <br />
        /// 注意:<see cref="ValidChars"/> 和 <see cref="InvalidChars"/> 最多一个不为 null 。
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DefaultValue(null)]
        private IList<char> InvalidChars
        {
            get { return invalidChars; }
            set
            {
                if (invalidChars != value)
                {
                    if (value != null)
                    {
                        ValidChars = null;
                    }
                    invalidChars = value;
                }
            }
        }

        private IList<char> invalidChars;

        private TextBoxBase TextBox { get; set; }

    }

}

namespace System.Windows.Forms
{
    using System.ComponentModel;

    /// <summary>
    /// 支持移除 非法字符 的输入框。
    /// </summary>
    public class RemoveInvalidCharTextBox : TextBox
    {
        /// <summary>
        /// 测试代码:设置 有效字符 为 整数 的字符。
        /// </summary>
        [System.Diagnostics.Conditional("DEBUG")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("", "IDE0017")]
        public static void TestValidCharAsInteger()
        {
            var form = new System.Windows.Forms.Form();
            var textBox = new RemoveInvalidCharTextBox();
            textBox.Dock =System.Windows.Forms.DockStyle.Top;
            textBox.UpdateValidCharAsInteger();
            form.Controls.Add(textBox);
            System.Windows.Forms.Application.Run(form);
        }

        public RemoveInvalidCharTextBox()
        {
            RemoveCharService = new TextBoxBaseRemoveCharService(this);
        }

        protected override void OnTextChanged(EventArgs e)
        {
            RemoveCharService?.OnTextChangedBefore();
            base.OnTextChanged(e);
        }

        /// <summary>
        /// 更新 有效字符 为 整数 的字符。
        /// </summary>
        public void UpdateValidCharAsInteger()
        {
            RemoveCharService.UpdateValidCharAsInteger();
        }

        private TextBoxBaseRemoveCharService RemoveCharService { get; set; }

        /// <summary>
        /// 禁止移除非法字符。
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DefaultValue(false)]
        public bool DisabledRemoveInvalidChars
        {
            get { return RemoveCharService.DisabledRemoveInvalidChars; }
            set { RemoveCharService.DisabledRemoveInvalidChars = value; }
        }
    }

}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2261684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nginx主要知识点总结

1下载nginx 到nginx官网nginx: download下载nginx&#xff0c;然后解压压缩包 然后双击nginx.exe就可以启动nginx 2启动nginx 然后在浏览器的网址处输入localhost&#xff0c;进入如下页面说明nginx启动成功 3了解nginx的配置文件 4熟悉nginx的基本配置和常用操作 Nginx 常…

如何跟进项目

在跟进项目的过程中&#xff0c;我们需要通过清晰的沟通和高效的执行来确保目标按时达成。简单来说&#xff0c;“如何跟进项目”可归纳为&#xff1a;明确目标和交付物、建立高效沟通机制、持续监控进度与风险、灵活应对变更。尤其是“明确目标和交付物”这一点&#xff1a;当…

获取微信用户openid

附上开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html 开发之前,准备事项 一个已认证过的服务号|基本信息配置js域名和网站授权域名配置最后确认当前账号网页授权功能是否开通,没有开通的无法获取到用户授权开发人…

【WRF工具】WRF 模型评估MET(Model Evaluation Tools)

WRF 模型评估MET&#xff08;Model Evaluation Tools&#xff09; METplus 简介WRF 模型评估工具 MET 的安装与使用步骤安装步骤使用步骤 参考 METplus 简介 METplus 是一个增强型的模型评估和验证框架&#xff0c;支持从短期预报&#xff08;如实时警报&#xff09;到长期气候…

ARMS 用户体验监控正式发布原生鸿蒙应用 SDK

作者&#xff1a;杨兰馨&#xff08;楠瑆&#xff09; 背景 2024 年 10 月 22 日&#xff0c;华为正式发布了原生鸿蒙操作系统&#xff08;HarmonyOS NEXT&#xff09;。原生鸿蒙实现了系统底座全部自研&#xff0c;系统的流畅度、性能、安全特性等方面显著提升&#xff0c;也…

云计算HCIP-OpenStack04

书接上回&#xff1a; 云计算HCIP-OpenStack03-CSDN博客 12.Nova计算管理 Nova作为OpenStack的核心服务&#xff0c;最重要的功能就是提供对于计算资源的管理。 计算资源的管理就包含了已封装的资源和未封装的资源。已封装的资源就包含了虚拟机、容器。未封装的资源就是物理机提…

MyBatis-Plus 实用工具:SqlHelper

SqlHelper 是MyBatis-Plus的一款SQL 辅助工具类&#xff0c;提供了一些常用的方法&#xff0c;简便我们的操作&#xff0c;提高开发效率。文档 最常用的是SqlHelper.table(Obj.class) 返回的 TableInfo 对象通常包含以下常用方法&#xff1a; 1. getTableName() 获取表名。示例…

压力测试Jmeter简介

前提条件&#xff1a;要安装JDK 若不需要了解&#xff0c;请直接定位到左侧目录的安装环节。 1.引言 在现代软件开发中&#xff0c;性能和稳定性是衡量系统质量的重要指标。为了确保应用程序在高负载情况下仍能正常运行&#xff0c;压力测试变得尤为重要。Apache JMeter 是一…

QT6 Socket通讯封装(TCP/UDP)

为大家分享一下最近封装的以太网socket通讯接口 效果演示 如图&#xff0c;界面还没优化&#xff0c;后续更新 废话不多说直接上教程 添加库 如果为qmake项目中&#xff0c;在.pro文件添加 QT network QT core gui QT networkgreaterThan(QT_MAJOR_VERS…

函数指针的作用

函数指针的主要作用&#xff0c;就是用来选择不同的调度函数&#xff0c;来满足特殊需求。它的优点&#xff0c;使程序设计更加灵活。缺点&#xff1a;初学者很难理解函数指针&#xff0c;从而引起程序的可读性不高。 1、使用函数指针选择调度函数 #include "stm32f10x.…

DateRangePickerDialog组件的用法

文章目录 概念介绍使用方法示例代码我们在上一章回中介绍了DatePickerDialog Widget相关的内容,本章回中将介绍DateRangePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里说的DateRangePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为…

【LeetCode每日一题】——220.存在重复元素 III

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 数组 二【题目难度】 困难 三【题目编号】 220.存在重复元素 III 四【题目描述】 给你一个…

SQL server学习07-查询数据表中的数据(下)

目录 一&#xff0c;自连接查询 二&#xff0c;多表查询 三&#xff0c;关系代数运算 1&#xff0c;笛卡尔乘积运算 1&#xff09;交叉连接 2&#xff0c;连接运算 2&#xff09;内连接 四&#xff0c;外连接 1&#xff0c;左外连接 2&#xff0c;右外连接 3&…

Three.js资源-模型下载网站

在使用 Three.js 进行 3D 开发时&#xff0c;拥有丰富的模型资源库可以大大提升开发效率和作品质量。以下是一些推荐的 Three.js 模型下载网站&#xff0c;它们提供了各种类型的 3D 模型&#xff0c;适合不同项目需求。无论你是需要逼真的建筑模型&#xff0c;还是简单的几何体…

景联文科技入选中国信通院发布的“人工智能数据标注产业图谱”

近日&#xff0c;由中国信息通信研究院、中国人工智能产业发展联盟牵头&#xff0c;联合中国电信集团、沈阳市数据局、保定高新区等70多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业&#xff0c;入选图谱中技术服务板块。…

WebView2与Chrome内核的区别和使用场景详细介绍

背景 近期有不少朋友使用了HTML一键打包EXE工具中的Webview2(免费)内核,询问的比较多的就是Webview2和Chrome内核的区别, 这里会给大家做一个简单的介绍. WebView2 是由微软提供的一种控件&#xff0c;它允许开发人员在本机应用程序中嵌入 web 技术&#xff08;如 HTML、CSS …

STM32F407ZGT6-UCOSIII笔记3:任务挂起与恢复实验

本文学习与程序编写基于 正点原子的 STM32F1 UCOS开发手册 编写熟悉一下UCOSIII系统的任务挂起与恢复实验 文章提供测试代码讲解、完整工程下载、测试效果图 目录 任务挂起与恢复目的&#xff1a; 任务挂起的目的 任务恢复的目的 任务函数文件&#xff1a; 任务块头文件 #in…

vue使用pdfh5.js插件,显示pdf文件白屏

pdfh5&#xff0c;展示文件白屏&#xff0c;无报错 实现效果图解决方法(降版本)排查问题过程发现问题查找问题根源1、代码写错了&#xff1f;2、预览文件流的问题&#xff1f;3、pdfh5插件更新了&#xff0c;我的依赖包没更新&#xff1f;4、真相大白 彩蛋 实现效果图 解决方法…

脚本搭建论坛

先创建这个目录&#xff1a; 在这个目录中写多个.sh脚本&#xff1a; 将论坛的压缩包放到/var/www/html目录下&#xff1a; 执行main.sh脚本。 Windows网页网址栏输入192.168.234.112/upload/ &#xff08;服务器ip地址&#xff09;&#xff0c;就可以安装了。

摩方M600_更换散热

研究了半天。参考了很多贴吧&#xff0c;哔哩哔哩的网友的方案。最后采用如下&#xff1a; 使用 apx90x47 散热器。散热静音效果很好。温度基本不到80度。作为对比 猫头鹰l9i 会到90温度墙。毕竟两个散热功率不一样。前置在 130w&#xff0c;后者65w。不过开始不懂&#xff0c…