0

我有一个带有 RichTextBox 的 Windows 窗体。RichTextBox 的内容被写入限制为 64k 数据的数据库字段。就我的目的而言,存储的文本绰绰有余。

我设置了 MaxLength 属性以避免插入比允许更多的数据。

rtcControl.MaxLength = 65536

但是,这只限制了允许在文本中放入的字符数量。但是由于 Rtf 的格式化开销,我可以输入比我应该允许的更多的文本。如果我插入一个大图像,它甚至会变得更糟,它根本不会增加 TextLength 但 Rtf 长度会增长很多。

目前,我在 FormClosing 事件中检查 Richttextboxes 的 Rtf 属性的长度,如果它太大,则向用户显示一条消息。但是,这只是一种解决方法,因为我想禁止将超过允许的数据放入控件中(例如在文本框中,如果您超过 MaxLength 属性,则不会将任何内容插入到控件中并且您会听到默认的 beep()。

任何想法如何实现这一目标?

我已经尝试过:

  • 使用自定义控件扩展了richtextbox 和阴影 th Rtf 属性来拦截插入。但是,如果我添加文本,它似乎不会执行。

  • 如果我输入 smth,即使 TextChanged 事件也不会触发。在控制中。

4

2 回答 2

1

这样做怎么办:

处理 TextChanged 事件并在每次更改时进行比较。它触发文本输入和图像拖放。

private void richTextBox1_TextChanged(object sender, EventArgs e)
{
   if (richTextBox1.Rtf.Length > richTextBox1.MaxLength)
   {
      // do something here - I displayed a label for
      // my example 
      label1.Text = "Text exceeds maximum size";
      label1.ForeColor = Color.Red;
   }
   else
   {
      label1.Text = richTextBox1.Rtf.Length.ToString();
      label1.ForeColor = Color.Red;
   }
}

诚然,这似乎奏效了,尽管我没有花很多时间在这上面。我怀疑如果内容超过最大大小,您可能会截断内容。


编辑:我对此进行了更多考虑,我怀疑您可以使用 StringBuilder 每次都存储富文本框的内容,如果有人试图超过该长度,则将数据恢复到以前的状态。我承认这有点hacky,但它似乎有效。像这样的东西:

StringBuild sb = new StringBuilder();

private void richTextBox1_TextChanged(object sender, EventArgs e)
{
   if (richTextBox1.Rtf.Length > richTextBox1.MaxLength)
   {
      richTextBox1.Rtf = sb.ToString();
   }
   else
   {
      sb.Insert(0,richTextBox1.Rtf);
   }
}

这似乎工作得很好。可能有一个更优雅的解决方案。

于 2010-04-15T13:10:29.797 回答
0

回应itsmatt:

这有效,除了 TextChanged 事件在我的环境中似乎没有触发(不知道为什么)。但是因为我有自己的用户控件,它是从 RichTextBox 中继承的,所以我能够覆盖调用的 OnTextChanged() 方法。但是代码有点复杂,因为如果您更改 OnTextChanged() 方法中的文本,它会再次被调用,这会导致 StackOverflowException。我还想要一个 Beep() 并且应该记住光标位置/选择。

使用此代码,文本 > 30000 会有点慢,但这对我来说已经足够了。无论如何,用户不应该在其中存储这么多数据。

    private string lastText;
    private string lastRtf;
    private int lastSelectionStart;
    private int lastSelectionLength;

    private bool skipLengthCheck;
    protected override void OnTextChanged(EventArgs e)
    {
        if (Rtf.Length > MaxLength && !skipLengthCheck)
        {
            skipLengthCheck = true;
            Console.WriteLine("MaxLength exceeded");
            System.Media.SystemSounds.Beep.Play();
            int start = lastSelectionStart;
            int length = lastSelectionLength;
            base.Text = lastText;
            base.Rtf = lastRtf;
            SelectionStart = start > 0 ? start - 1 : 0;
            SelectionLength = length;
            skipLengthCheck = false;               
        }
        else
        {
            lastText = Text;
            lastRtf = Rtf;

            base.OnTextChanged(e);
        }

    }

    protected override void OnSelectionChanged(EventArgs e)
    {
        lastSelectionStart = SelectionStart;
        lastSelectionLength = SelectionLength;

        base.OnSelectionChanged(e);
    }
于 2010-04-15T16:26:12.980 回答