我正在使用自定义控件watermark textbox
并且它很完美,但问题是我无法将水印textAlign更改为居中或从右到左。
默认情况下,它是从左到右,我怎样才能使它成为中心或从右到左?
这是代码:
Imports System.ComponentModel
Public Class Watermark
Inherits TextBox
'Declare A Few Variables
Dim WaterText As String
Dim WaterColor As Color
Dim WaterFont As Font
Dim WaterBrush As SolidBrush
Dim WaterContainer As Panel
Public Sub New()
MyBase.New()
StartProcess()
End Sub
Private Sub StartProcess()
'Assign Values To the Variables
WaterText = "Default Watermark"
WaterColor = Color.Gray
WaterFont = New Font(Me.Font, FontStyle.Italic)
WaterBrush = New SolidBrush(WaterColor)
CreateWatermark()
AddHandler TextChanged, AddressOf ChangeText
AddHandler FontChanged, AddressOf ChangeFont
End Sub
Private Sub CreateWatermark()
WaterContainer = New Panel
Me.Controls.Add(WaterContainer)
AddHandler WaterContainer.Click, AddressOf Clicked
AddHandler WaterContainer.Paint, AddressOf Painted
End Sub
Private Sub RemoveWatermark()
Me.Controls.Remove(WaterContainer)
End Sub
Private Sub ChangeText(sender As Object, e As EventArgs)
If Me.TextLength <= 0 Then
CreateWatermark()
ElseIf Me.TextLength > 0 Then
RemoveWatermark()
End If
End Sub
Private Sub ChangeFont(sender As Object, e As EventArgs)
WaterFont = New Font(Me.Font, FontStyle.Italic)
End Sub
Private Sub Clicked(sender As Object, e As EventArgs)
Me.Focus()
End Sub
Private Sub Painted(sender As Object, e As PaintEventArgs)
WaterContainer.Location = New Point(2, 0)
WaterContainer.Anchor = AnchorStyles.Left Or AnchorStyles.Right
WaterContainer.Height = Me.Height
WaterContainer.Width = Me.Width
WaterBrush = New SolidBrush(WaterColor)
Dim Graphic As Graphics = e.Graphics
Graphic.DrawString(WaterText, WaterFont, WaterBrush, New PointF(-2.0!, 1.0!))
End Sub
Protected Overrides Sub OnInvalidated(e As System.Windows.Forms.InvalidateEventArgs)
MyBase.OnInvalidated(e)
WaterContainer.Invalidate()
End Sub
<Category("Watermark Attributes"), Description("Sets Watermark Text")> Public Property WatermarkText As String
Get
Return WaterText
End Get
Set(value As String)
WaterText = value
Me.Invalidate()
End Set
End Property
<Category("Watermark Attributes"), Description("Sets Watermark Color")> Public Property WatermarkColor As Color
Get
Return WaterColor
End Get
Set(value As Color)
WaterColor = value
Me.Invalidate()
End Set
End Property
End Class
答案 0 :(得分:2)
有几点需要注意:
CueBanner
的机制,它很容易通过表单代码或作为自定义控件实现Panel
之前,没有视觉提示(TB Cursor)
b)您的Panel / Cue文本在您开始输入之前不会消失。这似乎是你想要的,但它不是原生的通常工作方式(正如Visual Vincent在评论中指出的那样,有一个选项。我个人不记得看到它足以注册我了。) />
c)在本机实现中,Cue Text / Watermark使用与控件相同的字体。只有设置为Combobox
的{{1}}使用斜体(可能您从未注意到这一点)。DropDownList
被重复调用,通过每次创建一个新的CreateWatermark
来重新显示Watermark / CueText,但是你没有丢弃旧版本。请记住:如果您在代码中创建控件,则还需要将其置于,而不是仅将其从控件集合中删除。Panel
对象也是如此,尽管只有在TextBox上的Font
发生变化时才会有效。首先,回答您提出的问题 - 允许左,右,中心TextAlignment。
Font
Private Sub Painted(sender As Object, e As PaintEventArgs)
' this can all be moved to the CreateWatermark method
'WaterContainer.Location = New Point(0, 0)
'WaterContainer.Anchor = AnchorStyles.Left Or AnchorStyles.Right
'WaterContainer.Height = Me.Height
'WaterContainer.Width = Me.Width
Dim rect As New Rectangle(2, 1, Width - 8, Height - 2)
Dim TxtFlags As TextFormatFlags
Select Case TxtAlign
Case HorizontalAlignment.Center
TxtFlags = TextFormatFlags.HorizontalCenter
Case HorizontalAlignment.Left
TxtFlags = TextFormatFlags.Left
Case HorizontalAlignment.Right
TxtFlags = TextFormatFlags.Right
End Select
TextRenderer.DrawText(e.Graphics, WatermarkText, WFont, rect, WatermarkColor, TxtFlags)
End Sub
来绘制文本,这通常是控件的更好选择(保存TextRenderer
以绘制到位图和图像)Graphics.DrawString()
属性显示该属性,以防您希望它与WatermarkTextAlign
不同。如果没有,请使用Visual Vincent的部分版本或组合它们。TextBox
用法很简单:
Partial Friend Class NativeMethods
...
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Friend Shared Function SendMessage(hWnd As IntPtr, msg As Integer,
wParam As Integer,
<MarshalAs(UnmanagedType.LPWStr)> lParam As String) As Int32
End Function
Private Const EM_SETCUEBANNER As Integer = &H1501
Private Const CB_SETCUEBANNER As Int32 = &H1703
Friend Shared Sub SetCueText(ctl As Control, text As String)
If TypeOf ctl Is ComboBox Then
SendMessage(ctl.Handle, CB_SETCUEBANNER, 0, text)
Else
SendMessage(ctl.Handle, EM_SETCUEBANNER, 0, text)
End If
End Sub
End Class
您还可以创建一个从TextBox继承并在那里实现的控件(覆盖NativeMethods.SetCueText(tbPInvWM, "Enter text...")
NativeMethods.SetCueText(ComboBox1, "Select...")
)。这将允许Cue Text在设计时显示,但代码更少。
最后,使用内部控件有一种更简单的方法:
OnHandleCreated
而不是Panel
。您可以使用标签的Label
,Font
,TextAlign
和ForeColor
属性作为您公开的属性的支持字段。 Text
设置也可以进行镜像。这将消除与处理和绘制文本相关的所有问题。
RightToLeft
通过使标签可见或不可见来处理提示文本显示:
Public Class TextBoxEx
Inherits TextBox
Private WaterCtrl As Label
...
' Example of using label props as the backing field:
<Category("Watermark Attributes"),
Description("Sets Watermark Text"),
DefaultValue("Watermark Text")>
Public Property WatermarkText As String
Get
If WaterCtrl IsNot Nothing Then
Return WaterCtrl.Text
Else
Return ""
End If
End Get
Set(value As String)
If WaterCtrl IsNot Nothing Then
WaterCtrl.Text = value
End If
End Set
End Property
这不是所有的代码,但它应该给你一个开始,它既简单又行为更像本机版本。
答案 1 :(得分:1)
每次绘制水印时都会设置水印的位置。您只需检查TextBox的属性并确定放置水印的位置(但是在设置水印的大小后必须这样做)。
您还必须将水印的宽度设置为实际水印文本的宽度,否则您将无法进行任何对齐。
<input id="col_11" onclick="do_something()">