2011-09-21 27 views
5

Ghost TextGhostText使用VB.Net

好傢伙,我試圖創建一個使用過的文本框的標籤一鬼文本。我正在使用VB.Net2005。我做到了這一點與此代碼:

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 

有什麼辦法來減少這些代碼,這樣,當我嘗試添加另一個文本框我永遠不會有重新輸入一串代碼。我有使用模塊和類的基本知識,但我真的不知道如何將此應用於此項目。我是一個新手,如果你有任何教程可以幫助我解決這個問題,請給我一個鏈接。在此先感謝&上帝保佑。

+0

減少冗餘的關鍵是封裝功能的重用。也就是說,每寫一個自定義控件並使用它。 –

回答

5

創建一個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 

然後,使用這種自定義控件,而不僅僅是一個TextBox。你需要做的就是爲你添加的每個新控件設置GhostText屬性,而不是再次重做相同的邏輯。

+0

我懂了...謝謝加載男人!這是我的稱呼:) – aer

+1

@aerohn - 沒問題。謝謝:) –

+0

另一個問題。有沒有辦法單獨重新設置每個文本框的大小?因爲文本框的大小相同......在此先感謝 – aer

1

你可以把超過100處理器在1分,只是由,

它們分開例如:

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 

要:

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

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

1

我用一個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 

然後,我只需要在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