windows 限制 .net 文本框中的行数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1048425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:42:55  来源:igfitidea点击:

Limit number of lines in .net textbox

.netwindowswinforms

提问by Ramesh Soni

I am using the winforms textbox with multiline option ON. I want to limit the number of lines that can be entered in it. User should not be able to enter lines more than that.

我正在使用带有多行选项的 winforms 文本框。我想限制可以输入的行数。用户不能输入更多的行。

How can I achieve that?

我怎样才能做到这一点?

采纳答案by SO User

You need to check for

你需要检查

txtbox.Lines.Length

txtbox.Lines.Length

You need to handle this for 2 scenarios: 1. User is typing in the textbox 2. User has pasted text in the textbox

您需要在 2 种情况下处理此问题:1. 用户正在文本框中输入 2. 用户已在文本框中粘贴文本

User typing in textbox

用户在文本框中输入

You need to handle the key press event of the text box to prevent user from entering more lines when max lines are exceeded.

您需要处理文本框的按键事件,以防止用户在超过最大行数时输入更多行。

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

I have tested the above code. It works as desired.

我已经测试了上面的代码。它按需要工作。

User pastes some text in the textbox

用户在文本框中粘贴一些文本

To prevent the user from pasting more than the max lines, you can code the text changed event handler:

为了防止用户粘贴的行数超过最大行数,您可以编写文本更改事件处理程序:

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.");
    }
}

回答by Leo Leslin

This solution doesn't work because when you type continuously, it will be treated as 1 line irrespective of the no of lines you see on the screen.

此解决方案不起作用,因为当您连续键入时,无论您在屏幕上看到多少行,它都会被视为 1 行。

In order to resolve the same, you need to use the SendMessage API to count the no of lines you see on the screen. Here is the code.

为了解决相同的问题,您需要使用 SendMessage API 来计算您在屏幕上看到的行数。这是代码。

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

Along with this, you need to find out the cursor position in the text box, so that you can allow the user to type. In the previous code, once it reaches to 13 lines, user won't be able to type in any line. In order to overcome that, you have to find out, the cursor is in which line. Use the below code for that.

与此同时,您需要找出文本框中的光标位置,以便您可以允许用户输入。在前面的代码中,一旦达到 13 行,用户将无法输入任何行。为了克服这个问题,您必须找出光标在哪一行。使用下面的代码。

Declare this along with the API declaration

将此与 API 声明一起声明

Private Const EM_LINEFROMCHAR = &HC9

私有常量 EM_LINEFROMCHAR = &HC9

Below code must be placed in MouseDown, MouseUp, KeyDown and KeyUp events of the textbox.

下面的代码必须放在文本框的 MouseDown、MouseUp、KeyDown 和 KeyUp 事件中。

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

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

After finding out the LineNo, you can do the evaluation in the KeyPress event of the TextBox.

找出LineNo后,就可以在TextBox的KeyPress事件中进行求值了。

回答by santosh

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

回答by Emilie217

I know this is an old thread but here's my solution. You basically check if either the first or last character is out of the client area. For some reason, if the first character gets scrolled out of the box, its Y value will be greater than 0 which is why I also check it. This works for both line breaks, copy/paste and character wrapping.

我知道这是一个旧线程,但这是我的解决方案。您基本上检查第一个或最后一个字符是否在客户区之外。出于某种原因,如果第一个字符被滚动出框,它的 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

回答by Ksempac

Depending on what you're trying to achieve, there is also the MaxLength property to set the number of characters you can enter in the textbox (since a line may have a variable length).

根据您要实现的目标,还有 MaxLength 属性来设置您可以在文本框中输入的字符数(因为一行可能具有可变长度)。

回答by Ksempac

Limit to MAX_LINES with truncation for copy/paste.

限制为 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;
        }
    }

回答by Hemant

OK. How about defining a instance variable "lastKnownGoodText" and doing something like this:

好的。如何定义一个实例变量“lastKnownGoodText”并执行如下操作:

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