0

RichTextBox を含む Windows フォームがあります。RichTextBox のコンテンツは、64k データに制限されたデータベース フィールドに書き込まれます。私の目的では、それは保存するのに十分なテキストです。

許可されているよりも多くのデータを挿入しないように、MaxLength プロパティを設定しました。

rtcControl.MaxLength = 65536

ただし、これはテキストに入力できる文字数を制限するだけです。しかし、Rtf による書式設定のオーバーヘッドにより、許可されているよりも多くのテキストを入力できます。大きな画像を挿入するとさらに悪化します。TextLength はまったく増加しませんが、Rtf Length はかなり大きくなります。

現時点では、FormClosing イベントで richttextboxes の Rtf プロパティの長さを確認し、大きすぎる場合はユーザーにメッセージを表示します。ただし、これは単なる回避策です。これは、コントロールに許可されているよりも多くのデータを配置することを禁止したいためです (MaxLength プロパティを超えた場合、テキスト ボックスのように、コントロールには何も挿入されず、デフォルトの beep() が聞こえます)。

これを達成する方法はありますか?

私はすでに試しました:

  • richtextbox を拡張し、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 を使用して毎回リッチテキストボックスの内容を保存し、その長さを超えようとした場合は、データを以前の状態に復元できると思います。私はこれが少しハックであることを認めますが、うまくいくようです。このようなもの:

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 に答える