8

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

  1. 有什么方法可以设置最大字符数,而无需在Clear()达到自定义限制时调用自定义限制器?
  2. 无论如何,它可以容纳的绝对最大值是多少?是否仅受内存限制?
  3. 当达到最大值/内存已满时会发生什么?碰撞?前 x 行已清除?
  4. 仅手动清除前 x 行的最佳方法是什么?子串操作?

编辑:我已经测试它可以容纳超过 600k 个字符,不管MaxLength,此时我手动停止了程序并问了这个问题。

4

3 回答 3

12
  1. 当然。覆盖/阴影AppendTextText在派生类中。请参阅下面的代码。
  2. Text属性的支持字段是一个普通的旧字符串(私有字段System.Windows.Forms.Control::text)。所以最大长度是字符串的最大长度,即“2 GB,或大约 10 亿个字符”(参见System.String)。
  3. 你为什么不试试看呢?
  4. 这取决于您的性能要求。您可以使用该Lines属性,但请注意,每次调用它时,您的全部text内容都会在内部解析为行。如果您要突破内容长度的限制,这将是一个坏主意。因此,更快的方法(就执行而言,而不是编码而言)是压缩字符并计算 cr / lfs。您当然需要决定您正在考虑的行尾是什么。

MaxLength代码:即使以编程方式设置文本也强制执行属性:

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;
        }
    }
}
于 2012-04-04T14:17:54.643 回答
3

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

于 2015-08-12T12:58:57.207 回答
2

的Text属性System.Windows.Forms.TextBox是一个字符串,所以理论上可以是一个字符串的最大长度

于 2012-04-04T13:11:48.697 回答