5

重複の可能性:
richTextBoxがその中に画像を貼り付けないようにするにはどうすればよいですか?

を使用している場合、たとえば次のようRichtextboxないくつかの利点があります。Richtextbox

カラーフォントを使用できます

リージョンにカスタムフォントを設定する

その上にファイルを添付するなど。

写真を見てください: ここに画像の説明を入力してください

これが私の問題です:

テキストのみにすることはできますか?

私のプロジェクトでは、添付ファイルなどは一切不要です。画像を添付したり貼り付けたりしたくなかったので、「テキストのみ」を追加したいだけです。Richtextbox

どうやってやるの?

4

2 に答える 2

7

RichTextBoxにはImagesまたはObjectsコレクションがないため、RTFフォーマットコードを使用する必要があります。RichTextBoxのすべてのデータは、特別なフォーマットコードを含むプレーンテキストとして保存されます。これは、RTFプロパティを介してコントロールによって公開されます。このコード言語を読んだり変更したりする場合は、このコード言語を学ぶことが不可欠です。学習リソースはWeb全体で簡単に利用できます。たとえば、この概要を参照してください。RichTextBoxは、MS Wordなどのいくつかのフル機能エディターよりも単純化されたrtfコードを使用するため、通常、操作する前にデータをRTBにロードすると、多くの冗長データが削除されます。

簡単に言うと、「pict」または「object」コマンドで始まるrtfグループを検索する必要があることがわかりました。グループがネストされている可能性があることを知っていると、そこから最初のend-group charを見つけることはできません。グループ化のカウントを維持しながら、文字列charをcharごとに解析して、それらのグループの終わりを見つける必要があります。これで、文字列のその部分を削除するのに十分な情報が得られました。Rtfには複数の画像/オブジェクトグループが含まれている可能性があるため、すべてが削除されるまでこれを行う必要があります。これらのグループを削除した後にrtf文字列を返すサンプル関数を次に示します。

private string removeRtfObjects(string rtf)
{
    //removing {\pict or {\object groups
    string pattern = "\\{\\\\pict|\\{\\\\object";
    Match m = Regex.Match(rtf, pattern);
    while (m.Success) {
        int count = 1;
        for (int i = m.Index + 2; i <= rtf.Length; i++) {
            //start group
            if (rtf(i) == '{') {
                count += 1;
            //end group
            } else if (rtf(i) == '}') {
                count -= 1;
            }
            //found end of pict/object group
            if (count == 0) {
                rtf = rtf.Remove(m.Index, i - m.Index + 1);
                break; // TODO: might not be correct. Was : Exit For
            }
        }
        m = Regex.Match(rtf, pattern);
        //go again
    }
    return rtf;
}

これはいつ行う必要がありますか?貼り付けについてはすでに説明しましたが、挿入もあります。これらは、クリップボード情報を取得してそれに応じて処理するKeyDownイベントでトラップできます。自分で操作を処理したときにe.Handled=Trueを設定すると、コントロールがこのキーの組み合わせに対してデフォルトの処理を実行してはならないことを通知します。これは、ユーザーのクリップボードを破壊せずに画像の貼り付けをブロックする方法でもあります。例:

private void RichTextBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
    //aware of Paste or Insert
    if (e.Control && e.KeyCode == Keys.V || e.Shift && e.KeyCode == Keys.I) {
        if (Clipboard.ContainsImage || Clipboard.ContainsFileDropList) {
            //some images are transferred as filedrops
            e.Handled = true;
            //stops here
        } else if (Clipboard.ContainsData(DataFormats.Rtf)) {
            RichTextBox rtbox = new RichTextBox();
            //use a temp box to validate/simplify
            rtbox.Rtf = Clipboard.GetData(DataFormats.Rtf);
            this.RichTextBox1.SelectedRtf = this.removeRtfObjects(rtbox.Rtf);
            rtbox.Dispose();
            e.Handled = true;
        }
    }
}
于 2013-01-14T15:35:17.317 に答える
4

はい、可能です。

RichTextBox1_KeyDownでCtrl+Vを処理してから、クリップボードのデータ形式を確認します。データがプレーンテキストの場合は貼り付けます。データがRTFの場合は、(クリップボードの内容を変更せずにバッファー内で)プレーンテキストに変換して貼り付けます。他の種類のデータは貼り付けないでください。

これは、続行する方法を示すための部分的な例です。

private void richTextBox1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Control && e.KeyCode == Keys.V)  
    { 
            // suspend layout to avoid blinking
            richTextBox2.SuspendLayout();

            // get insertion point
            int insPt = richTextBox2.SelectionStart;

            // preserve text from after insertion pont to end of RTF content
            string postRTFContent = richTextBox2.Text.Substring(insPt);

            // remove the content after the insertion point
            richTextBox2.Text = richTextBox2.Text.Substring(0, insPt);

            // add the clipboard content and then the preserved postRTF content
            richTextBox2.Text += (string)Clipboard.GetData("Text") + postRTFContent;

            // adjust the insertion point to just after the inserted text
            richTextBox2.SelectionStart = richTextBox2.TextLength - postRTFContent.Length;

            // restore layout
            richTextBox2.ResumeLayout();

            // cancel the paste
            e.Handled = true;
    } 
} 
于 2013-01-14T15:37:39.473 に答える