2011-09-21 5 views
5

Ghost TextGhostText usando VB.Net

Ciao ragazzi, ho cercato di creare un testo fantasma utilizzando etichette sopra la caselle di testo. Sto usando VB.Net2005. Ho compiuto questo con questo codice:

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 

Esiste un modo per ridurre questo codice, in modo che quando provo ad aggiungere un altro caselle di testo non avrò mai riscrivere una serie di codici. Ho conoscenze di base n utilizzando Modulo e Classe ma non ho davvero alcuna idea su come applicare questo con questo progetto. Sono un novizio, e se hai qualche tutorial che potrebbe aiutarmi a risolvere questo problema, gentilmente dammi d link. Grazie in anticipo & Dio benedica.

+0

La chiave per ridurre la ridondanza è quello di incapsulare la funzionalità per riutilizzare. Cioè, scrivi un controllo personalizzato e usalo ogni volta. –

risposta

5

Creare un usercontrol. Il codice dietro l'UserControl potrebbe essere qualcosa di simile:

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 

Quindi, utilizzare questo controllo personalizzato invece di un TextBox. Tutto ciò che devi fare è impostare la proprietà GhostText per ogni nuovo controllo che aggiungi, invece di ripetere di nuovo la stessa logica.

+0

Ho capito ... grazie mille! ecco il mio saluto :) – aer

+1

@aerohn - nessun problema. Grazie :) –

+0

un'altra domanda. C'è un modo per ridimensionare ogni casella di testo individualmente? cos le caselle di testo sono della stessa dimensione ... Grazie in anticipo – aer

1

È possibile inserire più di 1 Handler in 1 Sub, semplicemente li separano da un ,

Ad esempio:

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 

A:

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

e così via

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

1

Ho usato una classe NativeWindow per fare questo:

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 

Poi ho solo bisogno di collegare il TextBox ad esso:

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