当前位置: 首页 > news >正文

C#实现智能提示输入,并增色显示

实现一个智能下拉提示输入的功能,使用RichTextBox实现,结合了ListBox 实现特定字符提示输入选项 并对关键选项标记颜色突出显示
效果如下:
在这里插入图片描述
代码如下:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;namespace SmartBox
{public class SmartRichTextBox : RichTextBox{private ListBox _suggestionList;private List<string> _variableList;private string _triggerChar = "#";private Form _parentForm;// 语法高亮颜色private Color _variableColor = Color.Blue;private Color _normalColor = Color.Black;// 用于防止重入的标记private bool _isHighlighting = false;public SmartRichTextBox(){_variableList = new List<string>{"username", "email", "phone", "address","date", "time", "user_id", "department"};InitializeSuggestionList();this.KeyDown += SmartRichTextBox_KeyDown;this.KeyUp += SmartRichTextBox_KeyUp;this.TextChanged += SmartRichTextBox_TextChanged;this.LostFocus += SmartRichTextBox_LostFocus;this.SelectionChanged += SmartRichTextBox_SelectionChanged;// 设置默认字体和颜色this.Font = new Font("Microsoft Sans Serif", 9f);this.ForeColor = _normalColor;}public List<string> VariableList{get { return _variableList; }set { _variableList = value; }}public string TriggerChar{get { return _triggerChar; }set { _triggerChar = value; }}public Color VariableColor{get { return _variableColor; }set { _variableColor = value; }}private void InitializeSuggestionList(){_suggestionList = new ListBox{Visible = false,Width = this.Width,Height = 120,Font = this.Font,BorderStyle = BorderStyle.FixedSingle};_suggestionList.Click += SuggestionList_Click;_suggestionList.KeyDown += SuggestionList_KeyDown;_suggestionList.MouseMove += SuggestionList_MouseMove;}protected override void OnParentChanged(EventArgs e){base.OnParentChanged(e);if (this.Parent != null){_parentForm = this.FindForm();if (_parentForm != null){_parentForm.Controls.Add(_suggestionList);_suggestionList.BringToFront();}}}protected override void OnSizeChanged(EventArgs e){base.OnSizeChanged(e);if (_suggestionList != null){_suggestionList.Width = this.Width;}}#region 事件处理private void SmartRichTextBox_KeyUp(object sender, KeyEventArgs e){if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey)return;ShowSuggestions();}private void SmartRichTextBox_KeyDown(object sender, KeyEventArgs e){if (!_suggestionList.Visible)return;switch (e.KeyCode){case Keys.Down:if (_suggestionList.Items.Count > 0){_suggestionList.SelectedIndex = 0;_suggestionList.Focus();}e.Handled = true;break;case Keys.Enter:ApplySuggestion();e.Handled = true;break;case Keys.Escape:HideSuggestions();e.Handled = true;break;}}private void SuggestionList_KeyDown(object sender, KeyEventArgs e){switch (e.KeyCode){case Keys.Enter:ApplySuggestion();e.Handled = true;break;case Keys.Escape:HideSuggestions();this.Focus();e.Handled = true;break;case Keys.Up:if (_suggestionList.SelectedIndex == 0){this.Focus();e.Handled = true;}break;}}private void SuggestionList_Click(object sender, EventArgs e){ApplySuggestion();}private void SuggestionList_MouseMove(object sender, MouseEventArgs e){// 鼠标悬停时高亮项int index = _suggestionList.IndexFromPoint(e.Location);if (index >= 0){_suggestionList.SelectedIndex = index;}}private void SmartRichTextBox_SelectionChanged(object sender, EventArgs e){// 选择改变时隐藏建议列表if (_suggestionList.Visible){HideSuggestions();}}private void SmartRichTextBox_LostFocus(object sender, EventArgs e){// 延迟隐藏,以便点击下拉列表BeginInvoke(new Action(() =>{if (!_suggestionList.Focused && !this.Focused){HideSuggestions();}}));}#endregion#region 语法高亮功能private void SmartRichTextBox_TextChanged(object sender, EventArgs e){if (!_isHighlighting){ApplySyntaxHighlighting();}}/// <summary>/// 应用语法高亮/// </summary>private void ApplySyntaxHighlighting(){_isHighlighting = true;try{// 保存当前选择位置和颜色int currentSelectionStart = this.SelectionStart;int currentSelectionLength = this.SelectionLength;Color currentSelectionColor = this.SelectionColor;// 首先重置所有文本为默认颜色this.SelectAll();this.SelectionColor = _normalColor;this.DeselectAll();// 高亮所有以#开头的变量HighlightVariables();// 恢复选择位置this.SelectionStart = currentSelectionStart;this.SelectionLength = currentSelectionLength;this.SelectionColor = currentSelectionColor;}finally{_isHighlighting = false;}}/// <summary>/// 高亮变量/// </summary>private void HighlightVariables(){string text = this.Text;// 使用正则表达式匹配以#开头的变量// 匹配模式:以#开头,后面跟着字母、数字、下划线,直到遇到空格或标点string pattern = @"#\w+";var matches = Regex.Matches(text, pattern);foreach (Match match in matches){// 检查匹配的变量是否在变量列表中(去掉#号)string variableName = match.Value.Substring(1); // 去掉#号if (_variableList.Contains(variableName, StringComparer.OrdinalIgnoreCase)){this.Select(match.Index, match.Length);this.SelectionColor = _variableColor;}}}/// <summary>/// 手动刷新高亮(在变量列表改变后调用)/// </summary>public void RefreshHighlighting(){ApplySyntaxHighlighting();}#endregion#region 下拉建议功能private void ShowSuggestions(){string text = this.Text;int cursorPos = this.SelectionStart;// 查找触发字符的位置int triggerIndex = text.LastIndexOf(_triggerChar, cursorPos - 1);if (triggerIndex >= 0){// 检查#号后面是否已经有空格或其他分隔符bool hasSpaceAfterTrigger = false;for (int i = triggerIndex + 1; i < cursorPos; i++){if (char.IsWhiteSpace(text[i]) || text[i] == '.' || text[i] == ',' || text[i] == ';'){hasSpaceAfterTrigger = true;break;}}if (!hasSpaceAfterTrigger){string searchText = text.Substring(triggerIndex + 1, cursorPos - triggerIndex - 1);var matches = _variableList.Where(v => v.StartsWith(searchText, StringComparison.OrdinalIgnoreCase)).ToList();if (matches.Count > 0){_suggestionList.Items.Clear();foreach (var match in matches){_suggestionList.Items.Add(match);}// 定位下拉列表Point location = this.Location;Control parent = this.Parent;while (parent != null && !(parent is Form)){location.Offset(parent.Location.X, parent.Location.Y);parent = parent.Parent;}_suggestionList.Location = new Point(location.X, location.Y + this.Height);_suggestionList.Visible = true;_suggestionList.BringToFront();if (_suggestionList.Items.Count > 0){_suggestionList.SelectedIndex = 0;}return;}}}HideSuggestions();}private void HideSuggestions(){_suggestionList.Visible = false;}private void ApplySuggestion(){if (_suggestionList.SelectedItem != null){string selectedVar = _suggestionList.SelectedItem.ToString();string text = this.Text;int cursorPos = this.SelectionStart;// 找到最后一个触发字符的位置int triggerIndex = text.LastIndexOf(_triggerChar, cursorPos - 1);if (triggerIndex >= 0){// 替换从触发字符到当前位置的文本string newText = text.Substring(0, triggerIndex) +_triggerChar + selectedVar +text.Substring(cursorPos);this.Text = newText;this.SelectionStart = triggerIndex + _triggerChar.Length + selectedVar.Length;// 应用语法高亮ApplySyntaxHighlighting();}HideSuggestions();this.Focus();}}#endregion#region 公共方法/// <summary>/// 添加变量到列表/// </summary>public void AddVariable(string variableName){if (!_variableList.Contains(variableName, StringComparer.OrdinalIgnoreCase)){_variableList.Add(variableName);RefreshHighlighting();}}/// <summary>/// 从列表中移除变量/// </summary>public void RemoveVariable(string variableName){_variableList.RemoveAll(v => v.Equals(variableName, StringComparison.OrdinalIgnoreCase));RefreshHighlighting();}/// <summary>/// 清空所有变量/// </summary>public void ClearVariables(){_variableList.Clear();RefreshHighlighting();}/// <summary>/// 获取所有高亮的变量(不包含#号)/// </summary>public List<string> GetHighlightedVariables(){var variables = new List<string>();string text = this.Text;string pattern = @"#\w+";var matches = Regex.Matches(text, pattern);foreach (Match match in matches){string variableName = match.Value.Substring(1);//判断不区分大小写if (_variableList.Contains(variableName, StringComparer.OrdinalIgnoreCase)){variables.Add(variableName);}}return variables.Distinct().ToList();}#endregion#region 重写方法protected override void OnTextChanged(EventArgs e){// 确保基类处理完成后再进行高亮base.OnTextChanged(e);}protected override void OnFontChanged(EventArgs e){base.OnFontChanged(e);if (_suggestionList != null){_suggestionList.Font = this.Font;}}#endregion}
}
http://www.dtcms.com/a/544451.html

相关文章:

  • CommunityToolkit.Mvvm框架
  • 快速创建Word箱单(1/2)
  • 营销型网站建设公司易网拓做网站属于什么费用
  • 马蜂窝网络营销网站建设手机编程工具
  • iOS 抓包实战 从原理到复现、定位与真机取证全流程
  • 宝塔反向代理后就访问不到django服务中间件匹配的图片文件夹中的图片了
  • 【网络核心协议全景解析】IP、TCP、UDP与HTTP(多表格深度对比)
  • GStreamer 和 FFmpeg 两大开源工具简要对比
  • Fastlane 结合 开心上架(Appuploader)命令行实现跨平台上传发布 iOS App 的完整方案
  • Rust 中 WebSocket 支持的实现:从协议到生产级应用
  • LangChain生态介绍与实战
  • 前端基础之《React(5)—webpack简介-集成CSS和SASS支持》
  • 国外手机网站源码邵阳 做网站公司
  • 机器学习(3)---线性算法,决策树,神经网络,支持向量机
  • 网站建设服务费属于什么科目中山 灯饰 骏域网站建设专家
  • 操作系统(9)虚拟内存-内存映射
  • 30. 文件IO (1)
  • 技术深析:衡石 Agentic BI 的架构革命与核心技术突破
  • UVa 12333 Revenge of Fibonacci
  • rank(A+E) >= rank(A)证明
  • 未来之窗昭和仙君(四十三)开发布草管理系统修仙版——东方仙盟筑基期
  • VMware 虚拟机网络故障
  • 河南省建设厅举报网站建网站需要多少资金
  • 网站开发常用的谷歌插件企业首次建设网站的策划流程
  • 计算机3D视觉:Pytorch3d的环境配置与初步使用
  • 国产化转型实战:制造业供应链物流系统从MongoDB至金仓数据库迁移全指南
  • 从零开始学 Rust:环境搭建、基础语法到实战项目全流程
  • S11e Protocol 完整白皮书
  • CUDA:通往大规模并行计算的桥梁
  • AR智能眼镜:变电站巡检误操作的“电子安全员”