2009-06-26 1 views
13

Sto utilizzando la casella di testo Winforms con l'opzione multilinea ON. Voglio limitare il numero di righe che possono essere inserite in esso. L'utente non dovrebbe essere in grado di immettere righe più di questo.Numero limite di righe nella casella di testo .net

Come posso ottenere quello?

+0

+1 Buona domanda –

+0

Ramesh, ho aggiunto una nuova soluzione per la mia risposta che impedirebbe agli utenti di aggiungere più linee quando le linee max vengono superati. Non è necessario modificare o troncare il valore della casella di testo esistente. Questo è quello che devi usare. –

+0

@Rashmi, ma questo non gestisce molti scenari. Come copia incolla, avvolgimento del testo ecc. –

risposta

13

È necessario verificare la presenza di

txtbox.Lines.Length

È necessario gestire questo per 2 scenari: 1. L'utente sta scrivendo nella casella di testo 2. L'utente ha incollato il testo nella casella di testo

utente digitazione nella casella di testo

È necessario gestire l'evento di pressione tasto della casella di testo per impedire all'utente di immettere più righe quando vengono superate le linee massime.

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

Ho testato il codice precedente. Funziona come desiderato

paste utente del testo nella casella di testo

Per evitare che l'utente incollare più che le linee di massima, è possibile codificare il testo gestore di eventi cambiato:

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 addestrata a risolvere problemi complessi è spesso messa alla prova dalla semplicità all'inizio! – Hemant

+0

L'utente non dovrebbe essere in grado di immettere più righe di quello –

+0

OK ... È possibile che sia necessario un motivo legittimo per farlo. Per favore vedi la mia risposta. – Hemant

-2

OK. Come sulla definizione di un variabile di istanza "lastKnownGoodText" e fare qualcosa di simile:

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

È un buon approccio. Anche se non sono sicuro di lastKnownGoodText. Può essere drasticamente diverso se l'utente fa un copia-incolla per inserire il testo e potrebbe perdere il testo appena copiato. Perché non troncare invece? –

+0

Sì, hai ragione. Dovrebbe essere troncato piuttosto che essere ripristinato per l'ultima versione conosciuta. – Hemant

+0

Ho modificato la mia risposta che ora non ha bisogno di troncamenti. –

0

seconda di cosa si sta cercando di raggiungere, c'è anche la proprietà MaxLength per impostare il numero di caratteri che è possibile inserire nella casella di testo (poiché una linea può avere una lunghezza variabile).

+3

MaxLength non aiuta a limitare il no delle linee. –

0

Limite a MAX_LINES con troncamento per copia/incolla.

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

Questa soluzione non funziona perché quando si digita continuo, sarà trattata come 1 riga indipendentemente il no di linee che si vedono sullo schermo.

Al fine di risolvere lo stesso, è necessario utilizzare l'API SendMessage per contare il no di linee che si vedono sullo schermo. Ecco il codice.

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 

Insieme a questo, è necessario trovare la posizione del cursore nella casella di testo, in modo da poter permettere all'utente di digitare. Nel codice precedente, quando raggiunge 13 righe, l'utente non sarà in grado di digitare alcuna riga. Per superare questo, devi scoprire, il cursore è in quale linea. Usa il codice qui sotto per quello.

dichiarare questo insieme alla dichiarazione API

Private Const EM_LINEFROMCHAR = & HC9

Questi codice deve essere inserito nel MouseDown, MouseUp, KeyDown e KeyUp eventi del testo.

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

Dopo aver trovato il numero di riga, è possibile eseguire la valutazione nell'evento KeyPress di 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

Ciao @santosh, e benvenuti a StackOverflow. Sarebbe bello se spiegassi cosa fa il codice e perché. – SWeko

0

So che questo è un thread vecchio ma ecco la mia soluzione. Fondamentalmente si controlla se il primo o l'ultimo carattere è fuori dall'area client. Per qualche ragione, se il primo carattere viene fatto scorrere fuori dalla scatola, il suo valore Y sarà maggiore di 0, motivo per cui anch'io lo controllo. Funziona sia per interruzioni di riga, copia/incolla e carattere.

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