You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:12:39