热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#学习教程:当焦点位于文本框的自动完成框时,禁用键事件分享

当焦点位于文本框的自动完成框时,禁用键事件在我的项目中有一个FormmainForm,其中有两个textBoxestxtUserName和txtPassword以及一个按钮btnL

当焦点位于文本框的自动完成框时,禁用键事件

在我的项目中有一个Form mainForm ,其中有两个textBoxes txtUserNametxtPassword以及一个按钮btnLogin

我给出了以下txtUserName属性:

txtUserName属性

 AutoCompleteCustomSource - Collection --> Administrator --> Clerk AutoCompleteMode - Suggest AutoCompleteSource - CustomSource 

btnLogin_Click事件

 if (txtUserName.Text.Equals("Administrator") && txtPassword.Text.Equals("123")) { //function to access admin features } else if (txtUserName.Text.Equals("Clerk") && txtPassword.Text.Equals("123")) { //function to access clerk features } else { MessageBox.Show("Please Enter correct details", "Login Error"); } 

我已经将mainForm keypreview设置为true并将实现的函数设置为mainForm keyDown事件,如下面的代码所示:

mainForm_KeyDownEvent

 if (e.KeyCode.Equals(Keys.Enter)) //Invokes whenever Enter is pressed { btnLogin_Click(sender,e); //login } 

现在我的问题是,只要焦点在txtUserName并按下A ,就会显示下拉列表以选择“Administrator”(在我在上面的属性中显示的集合中定义)。 当我在键盘上单击Enter ,它显示的是MessageBox而不是选择“Administrator”。 我知道这是在调用mainForm的keydown事件。 如何禁用keyDown事件,当它在文本框下拉菜单上时,我可以按enter键吗?

编辑
我在public form()尝试了以下代码public form() ? 不工作

 InitializeComponent(); if (txtUserName.AutoCompleteMode) { /* showing red scribbles */ this.KeyDown -= mainForm_KeyDown; } 

您根本不应该处理Enter键。 您可以删除KeyDown处理程序,而是使用表单的AcceptButton属性来设置按下Enter时“单击”的按钮。 当另一个控件已经处理了Enter键时,这已经不应该“点击”按钮了。

这对您的情况来说还不够,因为标准的Windows行为按Enter键按下默认按钮。 例如,按Win + R获取Run …对话框,开始键入C: Use,按Down选择C: Users,按Enter键,看看会发生什么。

为了覆盖该行为,您需要使文本框告诉表单它将处理Enter键本身,以便表单不会将其发送到默认按钮。 这可以通过创建派生类并重写IsInputKey来完成:

 public class MyTextBox : TextBox { protected override bool IsInputKey(Keys keyData) { return base.IsInputKey(keyData) || ((keyData & ~Keys.Shift) == Keys.Enter && IsDroppedDown); } } 

但是, TextBox使用SHAutoComplete函数实现自动完成,该函数会在幕后自动创建一个IAutoComplete对象 。 无法访问该对象,因此,无法创建我在IsInputKey使用的IsDroppedDown属性。 它将使用IAutoCompleteDropDown.GetDropDownStatus实现,但由于该对象不可访问,因此您无法(可靠地)确定是否显示下拉列表。

您需要在使用内置AutoComplete*属性的情况下实现自动完成,或者您需要始终禁止Enter键(删除上述&& IsDroppedDown中的&& IsDroppedDown IsInputKey )。

更新 :这里是如何手动创建IAutoComplete对象。 管理员和文员字符串是硬编码的。 GetDropDownStatus函数用于在下拉列表可见时禁止任何默认按钮对Enter的处理。 欢迎反馈。

IAutoComplete.cs:

 using System; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; [ComImport] [Guid("00bb2762-6a77-11d0-a535-00c04fd7d062")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [CoClass(typeof(IAutoCompleteClass))] interface IAutoComplete { void Init(HandleRef hwndEdit, IEnumString punkACL, string pwszRegKeyPath, string pwszQuickComplete); void Enable(bool fEnable); } 

IAutoComplete2.cs:

 using System; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; [Guid("EAC04BC0-3791-11d2-BB95-0060977B464C")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAutoComplete2 { void Init(HandleRef hwndEdit, IEnumString punkACL, string pwszRegKeyPath, string pwszQuickComplete); void Enable(bool fEnable); void SetOptions(AutoCompleteOptions dwFlag); AutoCompleteOptions GetOptions(); }; 

AutoCompleteOptions.cs:

 using System; [Flags] enum AutoCompleteOptions : int { NOne= 0x00, AutoSuggest = 0x01, AutoAppend = 0x02, Search = 0x04, FilterPrefixes = 0x08, UseTab = 0x10, UpDownKeyDropsList = 0x20, RtlReading = 0x40, WordFilter = 0x80, NoPrefixFiltering = 0x100, } 

IAutoCompleteDropDown.cs:

 using System; using System.Runtime.InteropServices; using System.Text; [Guid("3CD141F4-3C6A-11d2-BCAA-00C04FD929DB")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAutoCompleteDropDown { void GetDropDownStatus(out AutoCompleteDropDownFlags dwFlags, out StringBuilder wszString); void ResetEnumerator(); } 

AutoCompleteDropDownFlags.cs:

 using System; [Flags] enum AutoCompleteDropDownFlags : int { NOne= 0x00, Visible = 0x01 } 

IAutoCompleteClass.cs:

 using System; using System.Runtime.InteropServices; [ComImport] [Guid("00BB2763-6A77-11D0-A535-00C04FD7D062")] class IAutoCompleteClass { } 

EnumString.cs:

 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; class EnumString : IEnumString { const int E_INVALIDARG = unchecked((int)0x80070057); const int S_OK = 0; const int S_FALSE = 1; int current; string[] strings; public EnumString(IEnumerable strings) { this.current = 0; this.strings = strings.ToArray(); } public void Clone(out IEnumString ppenum) { ppenum = new EnumString(strings); } public int Next(int celt, string[] rgelt, IntPtr pceltFetched) { if (celt <0) return E_INVALIDARG; int num = 0; while (current  celt) { current = strings.Length; return S_FALSE; } current += celt; return S_OK; } } 

MyTextBox.cs:

 using System; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; public class MyTextBox : TextBox { IAutoComplete2 autoComplete; IAutoCompleteDropDown autoCompleteDropDown; public bool IsDroppedDown { get { if (autoCompleteDropDown == null) return false; AutoCompleteDropDownFlags dwFlags; StringBuilder wszString; autoCompleteDropDown.GetDropDownStatus(out dwFlags, out wszString); return (dwFlags & AutoCompleteDropDownFlags.Visible) != AutoCompleteDropDownFlags.None; } } protected override void CreateHandle() { base.CreateHandle(); autoComplete = (IAutoComplete2)new IAutoComplete(); autoCompleteDropDown = (IAutoCompleteDropDown)autoComplete; autoComplete.SetOptions(AutoCompleteOptions.AutoSuggest); autoComplete.Init(new HandleRef(this, this.Handle), new EnumString(new string[] { "Administrator", "Clerk" }), null, null); } protected override void DestroyHandle() { ReleaseAutoComplete(); base.DestroyHandle(); } protected override void Dispose(bool disposing) { if (disposing) { ReleaseAutoComplete(); } base.Dispose(disposing); } protected override bool IsInputKey(Keys keyData) { return base.IsInputKey(keyData) || ((keyData & ~Keys.Shift) == Keys.Enter && IsDroppedDown); } void ReleaseAutoComplete() { if (autoComplete != null) { Marshal.ReleaseComObject(autoComplete); autoComplete = null; autoCompleteDropDown = null; } } } 

您需要覆盖keydown事件处理程序。

  protected override void OnKeyDown(KeyEventArgs e) { //call original event handler. Remove it if you don't need it at all. base.OnKeyDown(e); //Insert your code here.... } 

试试这个。 希望在焦点位于txtUsername或其他位置时按Enter键不会造成任何问题

如果您在txtUserName写入并按Enter键, Admministrator使用regular expression从您的autocompletecustomsource选择您的Admministrator选项,焦点将转到txtPassword 。 我的正则表达式非常灵活你可以将它限制为跟随严格匹配从开始,也可以删除忽略大小写

Regex rg = new Regex("^" + txtUserName.Text);

  private void mainForm_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode.Equals(Keys.Enter))// && !txtUserName.Focus())// && intFlag.Equals(0)) { if (txtUserName.Text.Length > 0) { if (txtUserName.Focused) { Regex rg = new Regex(txtUserName.Text, RegexOptions.IgnoreCase); for (int i = 0; i  0) { btnLogin_Click(null, null); //login } else { //MessageBox.Show("Please Give a Password"); txtPassword.Focus(); } } else { //MessageBox.Show("Please Give a username"); txtUserName.Focus(); } } //if (txtPassword.ContainsFocus) //{ // btnLogin_Click(sender, e); //login //} //else //{ // this.txtPassword.Focus(); //} } 

实际上,你有两个问题。

首先,将txtUserName的AutoCompleteMode属性设置为“SuggestAppend”,而不是简单地“建议”。 这样,如果用户键入第一个字母或两个字母,则正确的条目将自动附加到txtUSerName.Text。

接下来,修改您的表单代码如下:

 void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode.Equals(Keys.Enter)) //Invokes whenever Enter is pressed { if (txtPassword.ContainsFocus) { btnLogin_Click(sender, e); //login } else { this.txtPassword.Focus(); } } } private void btnLogin_Click(object sender, EventArgs e) { if (txtUserName.Text.Equals("Administrator") && txtPassword.Text.Equals("123")) { MessageBox.Show("Administrator"); } else if (txtUserName.Text.Equals("Clerk") && txtPassword.Text.Equals("123")) { MessageBox.Show("Clerk"); } else { MessageBox.Show("Please Enter correct details", "Login Error"); } } 

在上面,Key Down事件处理代码测试以查看密码文本框是否具有焦点(意味着,用户已经设定了用户名和密码,并准备提交数据)。 如果是,则调用btnLogin_Click事件。 否则,(意思是,txtUserName可能具有焦点)控制被传递给txtPassword以继续数据输入。

更新:重新 &#8211; 你的评论:

简单地杀掉Key Down Event处理程序中的逻辑,如下所示:

修订的事件处理代码:

 void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode.Equals(Keys.Enter)) //Invokes whenever Enter is pressed { btnLogin_Click(sender, e); //login } } 

注意,另一个小的改进(考虑到代码的整体结构)将使用combobox来选择UserName,并将自动完成源设置为“ListItems”,然后输入与文本框相同的选项。 这要求用户从预定义列表中进行选择。 这仍然具有与之前类似的可扩展性问题,但如果用户在输入用户名数据时只是输入拼写错误,则会为用户消除不必要的步骤。

请记住,用户倾向于不喜欢弹出消息不必要的中断。 允许他们从下拉列表中选择适当的“用户名”,输入正确的密码,然后继续。

有一些更好的方法来完成所有这些,但这应该调整你的工作顺序。

最后,请注意,最终您可能希望找到一种更强大的方法来执行此类validation。 任何时候您需要添加用户(在您的代码中,似乎更多地定义为“组”,您将需要添加到条件事件处理树。

您可以检查加密文件或数据库中的持久用户名和密码,并在运行时将它们加载到字典或其他内容中。 然后在user / Password上执行键/值查找。

或者其他的东西。

无论如何,希望有所帮助。

更新2:完整的代码一次性完成。 这应该按照你要求的方式行事:

上述就是C#学习教程:当焦点位于文本框的自动完成框时,禁用键事件分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注&#8212;编程笔记

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.KeyDown +=new KeyEventHandler(Form1_KeyDown); } void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode.Equals(Keys.Enter)) //Invokes whenever Enter is pressed { btnLogin_Click(sender, e); //login } } private void btnLogin_Click(object sender, EventArgs e) { if (txtUserName.Text.Equals("Administrator") && txtPassword.Text.Equals("123")) { MessageBox.Show("Administrator"); } else if (txtUserName.Text.Equals("Clerk") && txtPassword.Text.Equals("123")) { MessageBox.Show("Clerk"); } else { MessageBox.Show("Please Enter correct details", "Login Error"); } } } } 


推荐阅读
  • 在项目部署后,Node.js 进程可能会遇到不可预见的错误并崩溃。为了及时通知开发人员进行问题排查,我们可以利用 nodemailer 插件来发送邮件提醒。本文将详细介绍如何配置和使用 nodemailer 实现这一功能。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 在Oracle数据库中,使用Dbms_Output.Put_Line进行输出调试时,若单行字符超过255个,则会遇到ORA-20000错误。本文介绍了一种有效的方法来处理这种情况,通过创建自定义包和视图,实现对长字符串的分割和正确输出。 ... [详细]
  • 本文详细介绍了 Java 中的 org.apache.hadoop.registry.client.impl.zk.ZKPathDumper 类,提供了丰富的代码示例和使用指南。通过这些示例,读者可以更好地理解如何在实际项目中利用 ZKPathDumper 类进行注册表树的转储操作。 ... [详细]
  • This pull request introduces the ability to provide comprehensive paragraph configurations directly within the Create Note and Create Paragraph REST endpoints, reducing the need for additional configuration calls. ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 本文介绍如何使用 Angular 6 的 HttpClient 模块来获取 HTTP 响应头,包括代码示例和常见问题的解决方案。 ... [详细]
  • 本文介绍如何使用MFC和ADO技术调用SQL Server中的存储过程,以查询指定小区在特定时间段内的通话统计数据。通过用户界面选择小区ID、开始时间和结束时间,系统将计算并展示小时级的通话量、拥塞率及半速率通话比例。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • Java项目分层架构设计与实践
    本文探讨了Java项目中应用分层的最佳实践,不仅介绍了常见的三层架构(Controller、Service、DAO),还深入分析了各层的职责划分及优化建议。通过合理的分层设计,可以提高代码的可维护性、扩展性和团队协作效率。 ... [详细]
  • 本文详细探讨了Android Activity中View的绘制流程和动画机制,包括Activity的生命周期、View的测量、布局和绘制过程以及动画对View的影响。通过实验验证,澄清了一些常见的误解,并提供了代码示例和执行结果。 ... [详细]
author-avatar
手机用户2502940425
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有