垂直居中文本框

最近因做一个项目需要,需要让文本框能够垂直居中。老惯例,百度,虽然这个问题老旧就有人问,但都没有很好答案。网上有个vb6的例程,通过sendmessage发送EM_SETRECTNP消息重新设置文本编辑区域位置来实现垂直居中,但例程有bus。偶重新修改下并用vb。net实现。详细请看代码

 

 

Imports System.ComponentModel

''' <summary>
''' 实现垂直居中并可以设置水印文本框
''' </summary>
''' <remarks></remarks>
Public Class textboxEx
    Inherits TextBox

    ''' <summary>
    ''' 文本框水印
    ''' </summary>
    ''' <remarks></remarks>
    <Category("自定义属性"), DefaultValue(""), Description("设置或获取文本框水印。")> _
    Property EmptyTextTip() As String
        Get
            Return _EmptyTextTip
        End Get
        Set(ByVal value As String)
            _EmptyTextTip = value
        End Set
    End Property
    Private _EmptyTextTip As String

    Private EmptyTextTipColor As Color = Color.DarkGray
    ''' <summary>
    ''' 设置是否垂直显示
    ''' </summary>
    ''' <remarks></remarks>
    <Category("自定义属性"), DefaultValue(True), Description("设置或获取文本框是否垂直居中。")> _
    Property VerticalMiddle() As Boolean
        Get
            Return _VerticalMiddle
        End Get
        Set(ByVal value As Boolean)
            _VerticalMiddle = value
        End Set
    End Property
    Private _VerticalMiddle As Boolean

    ' Private mHostCell As tbCell = Nothing
#Region " 垂直居中"


    Dim rc As RECT
    Dim nlines As Integer
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByRef lParam As RECT) As Int32
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Int32, ByRef lParam As Int32) As Int32
    Private Const EM_GETRECT = &HB2
    Private Const EM_SETRECTNP = &HB4
    Private Const EM_GETLINECOUNT = &HBA
    Private Const WM_PAINT As Integer = &HF

    Private Structure RECT
        Public Left As Int32
        Public Top As Int32
        Public Right As Int32
        Public Bottom As Int32
    End Structure

    '计算居中
    Private Sub textboxex_Layout(ByVal sender As Object, ByVal e As System.Windows.Forms.LayoutEventArgs) Handles Me.Layout
        SetVCenterText()
    End Sub
    Private Sub textboxex_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.TextChanged
        Dim i As Long = SendMessage(Handle, EM_GETLINECOUNT, 0, 0)
        If nlines <> i Then
            SetVCenterText()
            nlines = Lines.Count
        End If
    End Sub
    '设置垂直居中
    Private Sub SetVCenterText()
        If Not Multiline Then Return
        '计算新高度
        Dim sz As SizeF
        Using g As Graphics = Me.CreateGraphics

            sz = g.MeasureString(Text, Font, Me.Size)
            If sz.Height = 0 Then
                sz = g.MeasureString("H", Font, Me.Size)
            End If
        End Using
        Dim rect As RECT = rc
        rect.Top = (Me.ClientSize.Height - sz.Height) / 2 - 2
        rect.Bottom = Me.ClientRectangle.Bottom
        rect.Left = 1 'Me.ClientRectangle.Left
        rect.Right = Me.ClientRectangle.Right - 1
        If rect.Top < 1 Then Return
        Console.WriteLine(rect.Right)
        Call SendMessage(Handle, EM_SETRECTNP, 0&, rect)
        Refresh()
    End Sub
#End Region

#Region " 绘制水印"
    ''' <summary>
    ''' 绘制水印
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub WmPaint()
        Using graphics__1 As Graphics = Graphics.FromHwnd(MyBase.Handle)
            If Text.Length = 0 AndAlso Not String.IsNullOrEmpty(_EmptyTextTip) AndAlso Not Focused Then
                Dim format As TextFormatFlags = TextFormatFlags.EndEllipsis Or TextFormatFlags.VerticalCenter

                If RightToLeft = RightToLeft.Yes Then
                    format = format Or TextFormatFlags.RightToLeft Or TextFormatFlags.Right
                End If

                TextRenderer.DrawText(graphics__1, _EmptyTextTip, Font, MyBase.ClientRectangle, EmptyTextTipColor, format)
            End If
        End Using
    End Sub
#End Region

    Private Sub textboxex_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Leave
        '绘制水印
        WmPaint()
    End Sub
    '获取文本编辑区大小
    Private Sub textboxex_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
        Call SendMessage(Me.Handle, EM_GETRECT, 0, rc)
    End Sub

    Public Sub New()

    End Sub
End Class


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值