2011-09-21 20 views
5

Ghost TextGhostText utilizando VB.Net

Hola chicos, me trataron de crear un texto fantasma el uso de etiquetas más de los cuadros de texto. Estoy usando VB.Net2005. Lo logré con este código:

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 

¿Hay alguna manera de reducir este código, de modo que cuando intento añadir otros cuadros de texto que nunca tendré que volver a escribir un montón de códigos. Tengo conocimientos básicos sobre el uso de Módulo y clase, pero realmente no tengo idea de cómo aplicar esto con este proyecto. Soy un novato, y si tienes algún tutorial que pueda ayudarme a resolver este problema, amablemente dame un enlace. Gracias de antemano & Dios bendiga.

+0

La clave para reducir la redundancia es encapsular la funcionalidad de reutilizar. Es decir, escriba un control personalizado y úselo cada vez. –

Respuesta

5

Crea un usercontrol. El código detrás de su usercontrol podría ser algo como:

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 

A continuación, utilice este control personalizado en lugar de sólo una TextBox. Todo lo que necesita hacer es establecer la propiedad GhostText para cada nuevo control que agregue en lugar de volver a hacer la misma lógica otra vez.

+0

Lo tengo ... gracias cargas hombre! aquí está mi saludo :) – aer

+1

@aerohn - no hay problema. Gracias :) –

+0

otra pregunta. ¿Hay alguna manera de cambiar el tamaño de cada cuadro de texto de forma individual? porque los cuadros de texto son del mismo tamaño ... Gracias de antemano – aer

1

Se puede poner más de 1 Handler en 1 Sub, simplemente separarlos por un ,

Por ejemplo:

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 

Para:

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

y así sucesivamente

MSDN: Connect Multiple Events to a Single Event Handler in Windows Forms

1

he utilizado una clase NativeWindow para hacer esto:

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 

Entonces sólo tiene que conectar el TextBox a ella:

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