VB.NET登录表单占位符功能及后续异常问题求助
解决VB.NET登录表单的Enter键失效、密码字符不显示问题,优化占位符实现
嘿,我来帮你搞定这两个头疼的问题,顺便把占位符的实现改成更稳定的原生方式,避免手动绘制带来的各种兼容性问题:
1. 修复Enter键触发登录的功能
你之前的KeyPress事件失效,大概率是因为手动绘制占位符时的事件干扰。其实不用写每个TextBox的KeyPress事件,用Form的AcceptButton属性更简单可靠:
- 打开窗体设计器,选中
frmLogIn - 在右侧属性面板找到
AcceptButton,下拉选择你的登录按钮btnLOGIN - 搞定!现在不管在哪个TextBox按Enter,都会自动触发登录按钮的点击事件,完全不用额外写KeyPress代码
如果你偏要保留KeyPress事件,检查一下事件有没有正确绑定,然后把代码改成这样(合并两个TextBox的事件处理):
Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress, TextBox2.KeyPress If e.KeyChar = Chr(13) Then e.Handled = True ' 阻止默认的回车行为,避免光标跳走 btnLOGIN.PerformClick() ' 直接调用登录按钮的点击逻辑 End If End Sub
2. 修复PasswordChar不显示的问题
你用CreateGraphics在MouseMove里绘制占位符的方式,会和TextBox的密码掩码功能冲突,因为绘制的文本是直接盖在控件表面,不是原生的占位符逻辑。推荐用Windows Forms原生的提示文本(Cue Banner),完美兼容密码框:
实现原生Cue Banner(强烈推荐)
先添加API调用声明,然后在窗体加载时设置提示文本:
Imports System.Runtime.InteropServices Public Class frmLogIn ' 调用Windows API设置提示文本 <DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As String) As IntPtr End Function Private Const EM_SETCUEBANNER As Integer = &H1501 Private Sub frmLogIn_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 给用户名框设置提示文本 SendMessage(TextBox1.Handle, EM_SETCUEBANNER, 0, "Username") ' 给密码框设置提示文本,完全兼容PasswordChar SendMessage(TextBox2.Handle, EM_SETCUEBANNER, 0, "Password") ' 确保密码框的掩码生效,这里改成你想要的字符,比如* TextBox2.PasswordChar = "*" End Sub ' --- 你的其他原有代码(登录按钮、取消按钮逻辑等)--- End Class
这种原生方式的好处:
- 窗口最小化再恢复、拖动窗口时,提示文本不会消失(手动绘制会丢)
- 焦点进入TextBox时自动隐藏提示,离开且文本为空时自动显示,完全不会和输入内容叠加
- 完美支持密码框的掩码,输入密码时正常显示*(或你设置的字符)
如果你非要用手动绘制方式(不推荐)
那得把绘制逻辑移到TextBox的Paint事件里,并且只在没有焦点且文本为空时绘制,还要处理重绘:
Private Sub TextBox1_Paint(sender As Object, e As PaintEventArgs) Handles TextBox1.Paint ' 只有文本为空且没焦点时才绘制提示 If TextBox1.Text = "" And Not TextBox1.Focused Then e.Graphics.DrawString("Username", New Font("Microsoft Sans Serif", 12), Brushes.LightGray, 0, 0) End If End Sub Private Sub TextBox2_Paint(sender As Object, e As PaintEventArgs) Handles TextBox2.Paint If TextBox2.Text = "" And Not TextBox2.Focused Then e.Graphics.DrawString("Password", New Font("Microsoft Sans Serif", 12), Brushes.LightGray, 0, 0) End If End Sub ' 焦点变化时触发重绘,确保提示文本正确显示/隐藏 Private Sub TextBox1_GotFocus(sender As Object, e As EventArgs) Handles TextBox1.GotFocus TextBox1.Invalidate() End Sub Private Sub TextBox1_LostFocus(sender As Object, e As EventArgs) Handles TextBox1.LostFocus TextBox1.Invalidate() End Sub Private Sub TextBox2_GotFocus(sender As Object, e As EventArgs) Handles TextBox2.GotFocus TextBox2.Invalidate() End Sub Private Sub TextBox2_LostFocus(sender As Object, e As EventArgs) Handles TextBox2.LostFocus TextBox2.Invalidate() End Sub
这种方式需要处理更多事件,不如原生API稳定,还是推荐用第一种方法。
额外建议:修复SQL注入风险
你当前的登录SQL直接拼接用户输入,存在严重的SQL注入风险,改成参数化查询更安全:
' 替换原来的查询代码 Dim query As String = "SELECT * FROM eeldatabase.logininfo WHERE username = @username AND password = @password" COMMAND = New MySqlCommand(query, MyConn) ' 添加参数,避免注入 COMMAND.Parameters.AddWithValue("@username", TextBox1.Text) COMMAND.Parameters.AddWithValue("@password", TextBox2.Text)
内容的提问来源于stack exchange,提问作者Kino Filme
相关产品推荐
相关产品推荐

