简体   繁体   English

使用VB.Net的GhostText

[英]GhostText using VB.Net

鬼文

Hello guys, I tried to create a ghost text using Labels over the Textboxes. 大家好,我试图在Textboxes上使用Labels创建一个鬼文本 I am using VB.Net2005. 我正在使用VB.Net2005。 I accomplished this with this code: 我用这段代码完成了这个:

Public Class frmDataEntry

    Private Sub PhantomTextLastName()
        If txtLastName.Text = "" Then
            lblLastName.Visible = True
        Else
            lblLastName.Visible = False
        End If
    End Sub

    Private Sub PhantomTextFirstName()
        If txtFirstName.Text = "" Then
            lblFirstName.Visible = True
        Else
            lblFirstName.Visible = False
        End If
    End Sub

    Private Sub PhantomTextMiddleInitial()
        If txtMiddleInitial.Text = "" Then
            lblMiddleInitial.Visible = True
        Else
            lblMiddleInitial.Visible = False
        End If
    End Sub

    Private Sub txtLastName_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtLastName.Click
        lblLastName.Text = "Last Name"
    End Sub

    Private Sub txtLastName_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtLastName.KeyDown
        PhantomTextLastName()
    End Sub

    Private Sub txtLastName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtLastName.TextChanged
        PhantomTextLastName()
    End Sub

    Private Sub lblLastName_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblLastName.Click
        txtLastName.Focus()
    End Sub

    Private Sub txtFirstName_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtFirstName.Click
        lblFirstName.Text = "First Name"
    End Sub

    Private Sub txtFirstName_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtFirstName.KeyDown
        PhantomTextFirstName()
    End Sub

    Private Sub txtFirstName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFirstName.TextChanged
        PhantomTextFirstName()
    End Sub

    Private Sub lblFirstName_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblFirstName.Click
        txtFirstName.Focus()
    End Sub

    Private Sub lblMiddleInitial_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblMiddleInitial.Click
        txtMiddleInitial.Focus()
    End Sub

    Private Sub txtMiddleInitial_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtMiddleInitial.Click
        lblMiddleInitial.Text = "Middle I."
    End Sub

    Private Sub txtMiddleInitial_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtMiddleInitial.KeyDown
        PhantomTextMiddleInitial()
    End Sub

    Private Sub txtMiddleInitial_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMiddleInitial.TextChanged
        PhantomTextMiddleInitial()
    End Sub
End Class

Is there any way to reduce this code, so that when I try to add another Textboxes I'll never have to retype a bunch of codes. 有没有办法减少这个代码,所以当我尝试添加另一个文本框时,我将永远不必重新键入一堆代码。 I have basic knowledge n using Module and Class but I really don't have any idea on how to apply this with this project. 我有使用Module和Class的基本知识,但我真的不知道如何在这个项目中应用它。 I am a newbie, and if you have any tutorial that could help me solve this problem, kindly give me d link. 我是新手,如果你有任何教程可以帮助我解决这个问题,请给我链接。 Thanks in advance & God bless. 提前谢谢,上帝保佑。

Create a usercontrol . 创建一个usercontrol The code behind your usercontrol might be something like: usercontrol背后的代码可能是这样的:

 Public Class GhostTextbox

    Private _ghostText As String
    Public Property GhostText As String
        Get
            Return _ghostText
        End Get
        Set(ByVal Value As String)
            _ghostText = Value
        End Set
    End Property

    Public Property ActualText As String
        Get
            Return Me.TextBox1.Text
        End Get
        Set(ByVal Value As String)
            Me.TextBox1.Text = Value
        End Set
    End Property

    Private Sub PhantomText()
        If TextBox1.Text = "" Then
            Label1.Visible = True
        Else
            Label1.Visible = False
        End If
    End Sub

    Private Sub TextBox1_Click(sender As Object, e As System.EventArgs) Handles TextBox1.Click
        Label1.Text = GhostText
    End Sub

    Private Sub TextBox1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
        PhantomText()
    End Sub

    Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
        PhantomText()
    End Sub

    Private Sub GhostTextbox_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Label1.Text = GhostText
    End Sub
End Class

Then, use this custom control instead of just a TextBox . 然后,使用此自定义控件而不仅仅是TextBox All you need to do is set the GhostText property for each new control you add instead of redoing the same logic over again. 您需要做的就是为您添加的每个新控件设置GhostText属性,而不是重新重新使用相同的逻辑。

You can put more than 1 Handler in 1 Sub, just separate them by a , 你可以在1 Sub中放置1个以上的Handler,只需将它们分开,

For example: 例如:

Private Sub txtMiddleInitial_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMiddleInitial.TextChanged
    PhantomTextMiddleInitial()
End Sub

Private Sub txtFirstName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFirstName.TextChanged
    PhantomTextFirstName()
End Sub

Private Sub txtLastName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtLastName.TextChanged
    PhantomTextLastName()
End Sub

To: 至:

Private Sub txtControl_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtLastName.TextChanged, txtFirstName.TextChanged, txtMiddleInitial.TextChanged
    PhantomTextLastName()
End Sub

and so on 等等

MSDN: Connect Multiple Events to a Single Event Handler in Windows Forms MSDN:将多个事件连接到Windows窗体中的单个事件处理程序

I've used a NativeWindow class to do this: 我使用NativeWindow类来执行此操作:

Public Class WaterMark
  Inherits NativeWindow

  <DllImport("User32.dll")> _
  Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
  End Function

  <DllImport("user32.dll")> _
  Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Boolean
  End Function

  Private _TextBox As TextBox
  Private _EmptyMessage As String

  Private Const WM_PAINT As Integer = &HF

  Public Sub New(ByVal textBox As TextBox, ByVal emptyMessage As String)
    _TextBox = TextBox
    AddHandler _TextBox.TextChanged, AddressOf OnTextChanged
    _EmptyMessage = emptyMessage
    MyBase.AssignHandle(textBox.Handle)
  End Sub

  Private Sub OnTextChanged(ByVal sender As Object, ByVal e As EventArgs)
    If _TextBox.Text = String.Empty Then
      _TextBox.Invalidate()
    End If
  End Sub

  Public Overrides Sub ReleaseHandle()
    RemoveHandler _TextBox.TextChanged, AddressOf OnTextChanged
    MyBase.ReleaseHandle()
  End Sub

  Protected Overrides Sub WndProc(ByRef m As Message)
    MyBase.WndProc(m)
    If m.Msg = WM_PAINT AndAlso _TextBox.Text = String.Empty Then
      Dim dc As IntPtr = GetWindowDC(m.HWnd)
      Using g As Graphics = Graphics.FromHdc(dc)
        TextRenderer.DrawText(g, _EmptyMessage, _TextBox.Font, _TextBox.ClientRectangle, Color.Gray, Color.Empty, TextFormatFlags.Left Or TextFormatFlags.VerticalCenter)
      End Using
      ReleaseDC(m.HWnd, dc)
    End If
  End Sub
End Class

Then I just need to attach the TextBox to it: 然后我只需要将TextBox附加到它:

Private _WaterMark As WaterMark

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
  _WaterMark = New WaterMark(TextBox1, "Enter Something:")
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM