2009-06-26 22 views
13

Estoy usando el cuadro de texto winforms con la opción de líneas múltiples ON. Quiero limitar el número de líneas que se pueden ingresar en él. El usuario no debería poder ingresar líneas más que eso.Limite el número de líneas en el cuadro de texto .net

¿Cómo puedo lograr eso?

+0

+1 Buena pregunta –

+0

Ramesh, he añadido una nueva solución a mi respuesta que los usuarios puedan agregar más líneas cuando se exceden las líneas máx. No es necesario editar o truncar el valor del cuadro de texto existente. Esa es la que necesita usar. –

+0

@Rashmi, pero eso no maneja muchos escenarios. Al igual que copiar y pegar, ajuste de texto, etc. –

Respuesta

13

Es necesario comprobar para

txtbox.Lines.Length

Es necesario para manejar esto por 2 escenarios: 1. El usuario está escribiendo en el cuadro de texto 2. El usuario ha pegado el texto en el cuadro de texto

usuario escribiendo en el cuadro de texto

Debe manejar el evento de presionar la tecla del cuadro de texto para evitar que el usuario ingrese más líneas cuando se exceden las líneas máximas.

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; 
    } 
} 

He probado el código anterior. Funciona según lo deseado.

pastas usuario algún texto en el cuadro de texto

Para evitar que el usuario pegar más de las líneas max, que pueden codificar el texto cambiado controlador de eventos:

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

¡Una mente entrenada para resolver problemas complejos a menudo queda perpleja por la simplicidad al principio! – Hemant

+0

El usuario no debería poder ingresar líneas más que eso –

+0

OK ... Puede que tenga una razón legítima para hacerlo. Por favor mira mi respuesta. – Hemant

-2

OK. ¿Qué hay de la definición de una variable de instancia "lastKnownGoodText" y hacer algo como esto:

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

Es un buen enfoque. Aunque no estoy seguro sobre lastKnownGoodText. Puede ser drásticamente diferente si el usuario copia y pega para ingresar el texto y puede perder el texto recién copiado. ¿Por qué no truncar en su lugar? –

+0

Sí, tienes razón. Debería truncarse en lugar de restaurarse a la última versión conocida. – Hemant

+0

He editado mi respuesta, que ahora no necesita truncamiento. –

0

Dependiendo de lo que estamos tratando de lograr, también existe la propiedad MaxLength para establecer el número de caracteres que se pueden introducir en el cuadro de texto (dado que una línea puede tener una longitud variable).

+3

MaxLength no ayuda a limitar el número de líneas. –

0

Limite a MAX_LINES con truncamiento para copiar/pegar.

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; 
     } 
    } 
1

Esta solución no funciona porque cuando se escribe continuamente, esto será tratado como 1 línea independientemente de la ninguna de las líneas que se ven en la pantalla.

Para resolver el problema, debe usar SendMessage API para contar el número de líneas que ve en la pantalla. Aquí está el código.

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 

Junto con esto, es necesario averiguar la posición del cursor en el cuadro de texto, por lo que puede permitir al usuario escribir. En el código anterior, una vez que llega a 13 líneas, el usuario no podrá ingresar ninguna línea. Para superar eso, debes averiguarlo, el cursor está en qué línea. Usa el siguiente código para eso.

nuevas de esto, junto con la declaración de la API

Private Const EM_LINEFROMCHAR = & HC9

A continuación código debe ser colocado en eventos MouseDown, MouseUp, KeyDown y KeyUp del cuadro de texto.

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

Después de encontrar el LineNo, puede hacer la evaluación en el evento KeyPress del TextBox.

0
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; 
} 
+0

Hola @santosh, y bienvenidos a stackoverflow. Sería bueno si explicas qué hace el código y por qué. – SWeko

0

Sé que este es un hilo antiguo, pero esta es mi solución. Básicamente, verifica si el primer o el último personaje están fuera del área del cliente. Por alguna razón, si el primer personaje se desplaza de la caja, su valor Y será mayor que 0, por lo que también lo verifico. Esto funciona tanto para saltos de línea como para copiar/pegar y el ajuste de caracteres.

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 
Cuestiones relacionadas