Limit number of lines in a TextBox

Is there a simple way to limit the number of lines in a multi-line textbox that wraps  I want to be able to look for soft returns as well as hard returns.

Answer this question

Limit number of lines in a TextBox

  • Rushi Amin

    No, I think that can definitely work. Not much fun, but it can work. 
  • IBRAHIM ERSOY

    Yes, EM_GETLINECOUNT message is the one you are looking for.
    It returns total number of text lines in multilined TextBox/RichTextBox. For example: if you have single line of text wrapped into three lines, the message will return 3.
    Note that the message never returns value less than 1, it will return 1 in case of empty TextBox.

  • Thomas Schimming

    You know what I really miss  I could swear that somewhere along the way before .NET shipped, the Control class had a SendMessage method. Man, that was nice. EM_GETLINECOUNT is definitely the most direct solution, but I do hate the P/Invoke stuff...

    Good solution, given that they don't provide this information otherwise! 

  • virenkar

    Thanks, Erymuzuan. Turning WordWrap off isn't an option. I've already implemented a MaxLength property which works reasonably well considering I'm not using a fixed-length font. The problem there is that users can still press Enter any number of times up to the MaxLength.

    I found something about the SendMessage API function with the EM_GETLINECOUNT message but I haven't been able to get it to work yet. Before I delve any deeper, can anyone confirm that it does what I need it to do

  • Reeves

    Hi,

    Well, I think that TextBox.Lines property is all you need - read it carefully in the .NET Framework SDK. So, you may get the TextBox.Lines.Length and if it is higher than desired one - don't process enter key.

    Cheers,
    Gogou

  • mnrsmith

    For what it's worth, here is how you could use the EM_GETLINECOUNT message:


    Private Const EM_GETLINECOUNT As Integer = &HBA
    Private Declare Function SendMessageINT Lib "user32" Alias "SendMessageA" (ByVal hWnd as IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer


    Then to use it:


    NumOfLines = SendMessageINT(TBox.Handle, EM_GETLINECOUNT, 0,0)


    Unfortunately, EM_GETLINECOUNT must be sent using SendMessage, else you could use WndProc and Message.Create.

    This could easily be integrated into your own textbox (with one caveat):


    Public Class LimitLineTextBox
        Inherits TextBox

        Private m_MaxLines As Integer = 1

        Public Sub New()
            MyBase.New()
            Me.MultiLine = True
        End Sub

        <DefaultValue(1), Category("Behavior")> _
        Public Property MaxLines() As Integer
            Get
                Return m_MaxLines
            End Get
            Set(ByVal Value As Integer)
                If Value <= 0 Then
                    Throw New Exception("The Value of the Max Lines Property must be greater than 0")
                Else
                    m_MaxLines = Value
                End If
            End Set
        End Property

        Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
            Dim numLines As Integer = GetLineCount()
            If numLines > MaxLines Then
                e.Handled = True
            Else
                MyBase.OnKeyPress(e)
            End If
        End Sub

        Private Declare Function SendMessageINT Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

        Private Function GetLineCount() As Integer
            Const EM_GETLINECOUNT As Integer = &HBA
            Return SendMessageINT(Me.Handle, EM_GETLINECOUNT, 0, 0)
        End Function
    End Class


    The caveat is in the override of OnKeyPress.  You'll notice that I check the line count to determine if it's greater than the max allowable lines.  But, I do nothing to accomodate for the case when the line count equals the MaxLines.  This might be a big hurdle.  Also note that certain user actions such as resizing a form with this control anchored on it can result in the number of soft lines changing.  Another potential hurdle...  

    Hope this is helpful.


  • Loren Jensen

    Unfortunately, TextBox.Lines returns a collection of lines delimited with CR/LF--that is, it doesn't help if you need to determine how many WRAPPED lines there are. A new line starts when a user presses Enter. What's requested here (and what I've needed in the past) is a collection of the lines as they appear wrapped on screen. It always surprised me that there's no way to determine natively how many lines of text appear on the screen, without resorting to the Win32API. 
  • Galex Yen - MSFT

    i'm curious if there's a way to do it using GDI+'s MeasureString method...maybe pass it the region of the textbox and the font and divide by height of font   bah...i dunno  :~ 
  • Sync_Austin

    i can't find a way to limit the number of line natively. but there are work around . if your textbox WordWrap is false then you could hook the Text_Change/Key_Press and count the newline. but in your case the best i could recommend is to limit the MaxLength property and estimate the number of characters there would be for a desired number of line
  • Limit number of lines in a TextBox