关于c#:TextBox的最大字符数(不是MaxLength)

TextBox maximum amount of characters (it's not MaxLength)

我正在使用System.Windows.Forms.TextBox。根据文档,MaxLength属性控制输入的用户可以输入或粘贴到TextBox中的字符数量(即比通过使用AppendText函数或Text属性以编程方式添加的字符数量更多)。当前字符数可以从TextLength属性获得。

  • 是否有任何方法可以设置最大字符数而无需创建自定义限制器,当达到自定义限制时,该限制器将调用Clear()
  • 无论如何,它可以容纳的绝对最大值是多少?它仅受内存限制吗?
  • 当达到最大值/内存已满时会发生什么?崩溃了吗前x行已清除?
  • 手动清除前x行的最佳方法是什么?子串操作?
  • edit:我已经测试过它可以容纳超过60万个字符,而无论MaxLength是什么,在这一点上我都手动停止了程序并询问了这个问题。


  • 当然。在派生类中覆盖/阴影AppendTextText。请参见下面的代码。
  • Text属性的后备字段是一个普通的旧字符串(私有字段System.Windows.Forms.Control::text)。因此,最大长度是字符串的最大长度,即" 2 GB,或大约10亿个字符"(请参阅??System.String)。
  • 你为什么不试试看?
  • 这取决于您的性能要求。您可以使用Lines属性,但是请注意,每次调用它时,整个Text都将在内部解析为几行。如果您要限制内容长度的限制,那将是个坏主意。这样,更快的方式(就执行而言,而不是编码)将遍历字符并计算cr / lfs。您当然需要确定要考虑的行尾。
  • 代码:即使以编程方式设置文本,也强制执行MaxLength属性:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    using System;
    using System.Windows.Forms;
    namespace WindowsFormsApplication5 {
        class TextBoxExt : TextBox {
            new public void AppendText(string text) {
                if (this.Text.Length == this.MaxLength) {
                    return;
                } else if (this.Text.Length + text.Length > this.MaxLength) {
                    base.AppendText(text.Substring(0, (this.MaxLength - this.Text.Length)));
                } else {
                    base.AppendText(text);
                }
            }

            public override string Text {
                get {
                    return base.Text;
                }
                set {
                    if (!string.IsNullOrEmpty(value) && value.Length > this.MaxLength) {
                        base.Text = value.Substring(0, this.MaxLength);
                    } else {
                        base.Text = value;
                    }
                }
            }

            // Also: Clearing top X lines with high performance
            public void ClearTopLines(int count) {
                if (count <= 0) {
                    return;
                } else if (!this.Multiline) {
                    this.Clear();
                    return;
                }

                string txt = this.Text;
                int cursor = 0, ixOf = 0, brkLength = 0, brkCount = 0;

                while (brkCount < count) {
                    ixOf = txt.IndexOfBreak(cursor, out brkLength);
                    if (ixOf < 0) {
                        this.Clear();
                        return;
                    }
                    cursor = ixOf + brkLength;
                    brkCount++;
                }
                this.Text = txt.Substring(cursor);
            }
        }

        public static class StringExt {
            public static int IndexOfBreak(this string str, out int length) {
                return IndexOfBreak(str, 0, out length);
            }

            public static int IndexOfBreak(this string str, int startIndex, out int length) {
                if (string.IsNullOrEmpty(str)) {
                    length = 0;
                    return -1;
                }
                int ub = str.Length - 1;
                int intchr;
                if (startIndex > ub) {
                    throw new ArgumentOutOfRangeException();
                }
                for (int i = startIndex; i <= ub; i++) {
                    intchr = str[i];
                    if (intchr == 0x0D) {
                        if (i < ub && str[i + 1] == 0x0A) {
                            length = 2;
                        } else {
                            length = 1;
                        }
                        return i;
                    } else if (intchr == 0x0A) {
                        length = 1;
                        return i;
                    }
                }
                length = 0;
                return -1;
            }
        }
    }


    理论上的限制是大约2GB的字符串。但是,实际上,这取决于运行过程中的条件。它等于字符串在任何给定时间可以分配的最大可用连续内存部分的大小。我的应用程序中有一个文本框,错误大约为450MB。


    System.Windows.Forms.TextBox的Text属性是一个字符串,因此从理论上讲它可以是字符串的最大长度。