【问题标题】:How to Make RichTextBox Text Only? [duplicate]如何仅制作 RichTextBox 文本? [复制]
【发布时间】:2013-01-15 00:04:49
【问题描述】:

可能重复:
How to prevent richTextBox to paste images within it?

如果您使用RichtextboxRichtextbox 有几个优点,例如:

我们可以在上面使用彩色字体

在区域中设置自定义字体

在上面附加文件..等

看图:

这是我的问题:

我可以只写文字吗?

在我的项目中,根本不需要附加文件等。我什至不想在上面附加或粘贴图片,我只想在Richtextbox“纯文本”@

我该怎么做?

【问题讨论】:

标签: c# .net visual-studio-2008 richtextbox


【解决方案1】:

由于 RichTextBox 没有图像或对象集合,您必须使用 RTF 格式代码。 RichTextBox 的所有数据都存储为带有特殊格式代码的纯文本,这由控件通过其 RTF 属性公开。如果您想阅读或更改此代码语言,学习此代码语言是必不可少的,学习资源可在整个网络上轻松获得,例如,请参阅此概述。 RichTextBox 使用比 MS Word 等一些全功能编辑器更简化的 rtf 代码,因此在操作之前将数据加载到 RTB 通常是有益的,这将删除大量冗余数据。

长话短说,我发现有必要搜索以“pict”或“object”命令开头的 rtf 组。知道组可能是嵌套的,您不能只从那里找到第一个端组字符,您必须逐个字符地解析字符串,同时保持分组计数以找到这些组的末尾。现在您有足够的信息来删除字符串的那部分。 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;
        }
    }
}

【讨论】:

  • 哇很好,这是一个非常准确的答案。谢谢你的回答..
  • 你用过if (rtf(i) == '{')应该不是if (rtf[i] == '{')
  • 我稍微编辑了您的答案,以使您的代码示例对复制粘贴更加友好。
  • 我更喜欢if (Clipboard.ContainsText()) this.RichTextBox1.SelectedText = Clipboard.GetText(); 你不必做任何不必要的操作,它甚至适用于其他类型(HTML,计划文本...)。当剪贴板仅包含纯文本时,我不确定这是否会起作用。检查也不是最好的。 “Alt+Ctrl+V”会变成粘贴;不幸的是,至少在某些国家键盘中,这种组合用于插入@ 字符。附言我将“Keys.I”编辑为“Insert”,因为“Shift+I”不粘贴文本,只写i 字符。
【解决方案2】:

是的,有可能。

在 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;
    } 
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2018-04-29
    相关资源
    最近更新 更多