Ограничить количество строк в текстовом поле .net

Я использую текстовое поле winforms с многострочной опцией ON. Я хочу ограничить количество строк, которые можно ввести в него. Пользователь не должен иметь возможность вводить строки больше.

Как я могу это достичь?

Ответы

Ответ 1

Вам нужно проверить

txtbox.Lines.Length

Вам нужно обработать это для двух сценариев: 1. Пользователь вводит текст в текстовое поле. 2. Пользователь вставляет текст в текстовое поле.

Ввод пользователя в текстовое поле

Вам нужно обработать событие нажатия клавиши текстового поля, чтобы пользователь не мог ввести больше строк при превышении максимальных строк.

private const int MAX_LINES = 10;

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (this.textBox1.Lines.Length >= MAX_LINES && e.KeyChar == '\r')
    {
        e.Handled = true;
    }
}

Я тестировал вышеуказанный код. Он работает по своему желанию.

Пользователь вставляет текст в текстовое поле

Чтобы пользователь не вставлял больше, чем максимальные строки, вы можете закодировать обработчик событий с измененным текстом:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (this.textBox1.Lines.Length > MAX_LINES)
    {
        this.textBox1.Undo();
        this.textBox1.ClearUndo();
        MessageBox.Show("Only " + MAX_LINES + " lines are allowed.");
    }
}

Ответ 2

Это решение не работает, потому что, когда вы печатаете непрерывно, он будет рассматриваться как 1 строка, независимо от того, нет ли линий, которые вы видите на экране.

Чтобы решить эту проблему, вам нужно использовать API SendMessage для подсчета количества строк, которые вы видите на экране. Вот код.

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 Const EM_GETLINECOUNT = &HBA

Private Sub txtText1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtText1.KeyPress

    Const MAX_LINES = 13
    Dim lngCount As Long

    lngCount = SendMessageINT(txtText1.Handle, EM_GETLINECOUNT, 0, 0)

    If lngCount = MAX_LINES And Asc(e.KeyChar) <> Keys.Back And Asc(e.KeyChar) <> Keys.Delete Then
        e.Handled = True
    End If
End Sub

Кроме того, вам нужно найти позицию курсора в текстовом поле, чтобы вы могли разрешить пользователю вводить текст. В предыдущем коде, когда он достигнет 13 строк, пользователь не сможет ввести строку. Чтобы преодолеть это, вам нужно выяснить, в какой строке находится курсор. Для этого используйте код ниже.

Объявите это вместе с объявлением API

Частная константа EM_LINEFROMCHAR = & HC9

Ниже код должен быть помещен в события MouseDown, MouseUp, KeyDown и KeyUp в текстовое поле.

intLineNo = SendMessageINT (txtText1.Handle, EM_LINEFROMCHAR, -1, 0 &) + 1

После определения LineNo вы можете выполнить оценку в событии KeyPress в TextBox.

Ответ 3

В зависимости от того, что вы пытаетесь достичь, существует также свойство MaxLength для установки количества символов, которые вы можете ввести в текстовое поле (так как строка может иметь переменную длину).

Ответ 4

Ограничение MAX_LINES с усечением для копирования/вставки.

    private void textBox1_KeyDown( object sender, KeyEventArgs e )
    {
        if ( textBox1.Lines.Length >= MAX_LINES && e.KeyValue == '\r' )
            e.Handled = true;
    }

    private void textBox1_TextChanged( object sender, EventArgs e )
    {
        if ( textBox1.Lines.Length > MAX_LINES )
        {
            string[] temp = new string[MAX_LINES];
            for ( int i = 0; i < MAX_LINES; i++ )
            {
                temp[i] = textBox1.Lines[i];
            }

            textBox1.Lines = temp;
        }
    }

Ответ 5

private void txttrccertificateto_TextChanged(object sender, EventArgs e)
{
  if (txttrccertificateto.Text.Length > MAX_Char)
  {
    txttrccertificateto.Text = txttrccertificateto.Text.Remove(MAX_Char, 1);
  }
  if (txttrccertificateto.Lines.Length > MAX_LINES)
  {
    string[] temp = new string[MAX_LINES];
    for (int i = 0; i < MAX_LINES; i++)
    {
      temp[i] = txttrccertificateto.Lines[i];
    }

    txttrccertificateto.Lines = temp;
  }
}

private void txttrccertificateto_KeyDown(object sender, KeyEventArgs e)
{
  if (txttrccertificateto.Lines.Length >= MAX_LINES && e.KeyValue == '\r')
    e.Handled = true;
  if (txttrccertificateto.Text.Length >= MAX_Char && e.KeyValue == '\r')
    e.Handled = true;
}

private void txttrccertificateto_KeyUp(object sender, KeyEventArgs e)
{
  if (txttrccertificateto.Lines.Length >= MAX_LINES && e.KeyValue == '\r')
    e.Handled = true;
  if (txttrccertificateto.Text.Length >= MAX_Char && e.KeyValue == '\r')
    e.Handled = true;
}

Ответ 6

Я знаю, что это старый поток, но здесь мое решение. Вы в основном проверяете, находится ли первый или последний символ вне клиентской области. По какой-то причине, если первый символ прокручивается из коробки, его значение Y будет больше 0, поэтому я также проверю его. Это работает для разрывов строк, копирования/вставки и обертывания символов.

Private Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.TextChanged
     If Not Me.Multiline OrElse String.IsNullOrEmpty(Me.Text) OrElse _InTextChanged Then Exit Sub
     _InTextChanged = True

     Try
        Dim posLast As Point = Me.GetPositionFromCharIndex(Me.Text.Length - 1)
        Dim posFirst As Point = Me.GetPositionFromCharIndex(0)

        Dim sizeLast As SizeF
        Dim sizeFirst As SizeF

        Using g As Graphics = Graphics.FromHwnd(Me.Handle)
           sizeLast = g.MeasureString(Me.Text(Me.Text.Length - 1).ToString(), Me.Font)
           sizeFirst = g.MeasureString(Me.Text(0).ToString(), Me.Font)
        End Using

        If posLast.Y + sizeLast.Height > Me.ClientSize.Height OrElse posFirst.Y < 0 OrElse posFirst.Y + sizeFirst.Height > Me.ClientSize.Height Then

           Me.Text = _PreviousText

           If _PreviousSelectionStart > Me.Text.Length Then
              Me.SelectionStart = Me.Text.Length
           Else
              Me.SelectionStart = _PreviousSelectionStart
           End If


        End If
     Catch ex As Exception

     End Try

     _InTextChanged = False


  End Sub

  Private Sub Textbox_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
     _PreviousSelectionStart = Me.SelectionStart
     _PreviousText = Me.Text
  End Sub

Ответ 7

OK. Как определить переменную экземпляра lastKnownGoodText и сделать что-то вроде этого:

private void textBox_TextChanged (object sender, EventArgs e) {
    if (textBox.Lines.Length > 10)
        textBox.Text = lastKnownGoodText;
    else
        lastKnownGoodText = textBox.Text;
}