C#: 在RichTextBox中粘贴RTF文本但保留颜色和格式(例如:加粗,下划线等)

3

是否可以将文本粘贴到富文本框中,同时保留富文本框中使用的字体?

换句话说,我想从Word复制一些格式化的内容(即使用字体X并带有下划线和蓝色的文本),然后将其粘贴到我的RichTextBox中。

我希望被粘贴的内容具有与RichTextBox相同的字体,但保留其原始颜色和下划线。

这种情况是否可能?

我使用winforms。

谢谢


你问题的答案已经在我的帖子中找到了。“我使用winforms。” - Hussein Khalil
1
我非常确定,阅读完毕是提出问题的前提条件,但谢谢,我会将其添加到标签中的 ;). - Hussein Khalil
你并不是那么快;-) 很抱歉让你感到烦恼。 - Snowbear
5个回答

3
这是无法直接实现的。但您可以尝试以下方法:
public void SpecialPaste()
{
    var helperRichTextBox = new RichTextBox();
    helperRichTextBox.Paste();
    for(int i=0;i<helperRichTextBox.TextLength;++i)
    {
        helperRichTextBox.SelectionStart = i;
        helperRichTextBox.SelectionLength = 1;
        helperRichTextBox.SelectionFont = new Font(richTextBox1.SelectionFont.FontFamily, richTextBox1.SelectionFont.Size,helperRichTextBox.SelectionFont.Style);
    }

    richTextBox1.SelectedRtf = helperRichTextBox.Rtf;
}

这将改变粘贴的RTF字体,使其与插入符号位置前的字符字体相同。
如果你粘贴的文本较大,这可能会很快变得棘手。此外,可以进行优化,仅对具有与Hans建议相同基本字体的一行中的所有字符设置字体。

更新:
以下是经过优化的版本,它为具有相同原始字体的一组连接字符设置字体:

public void SpecialPaste()
{
    var helperRichTextBox = new RichTextBox();
    helperRichTextBox.Paste();
    helperRichTextBox.SelectionStart = 0;
    helperRichTextBox.SelectionLength = 1;

    Font lastFont = helperRichTextBox.SelectionFont;
    int lastFontChange = 0;
    for (int i = 0; i < helperRichTextBox.TextLength; ++i)
    {
        helperRichTextBox.SelectionStart = i;
        helperRichTextBox.SelectionLength = 1;
        if (!helperRichTextBox.SelectionFont.Equals(lastFont))
        {
            lastFont = helperRichTextBox.SelectionFont;
            helperRichTextBox.SelectionStart = lastFontChange;
            helperRichTextBox.SelectionLength = i - lastFontChange;
            helperRichTextBox.SelectionFont = new Font(richTextBox1.SelectionFont.FontFamily, richTextBox1.SelectionFont.Size, helperRichTextBox.SelectionFont.Style);
            lastFontChange = i;
        }
    }
    helperRichTextBox.SelectionStart = helperRichTextBox.TextLength-1;
    helperRichTextBox.SelectionLength = 1;
    helperRichTextBox.SelectionFont = new Font(richTextBox1.Font.FontFamily, richTextBox1.Font.Size, helperRichTextBox.SelectionFont.Style);

    richTextBox1.SelectedRtf = helperRichTextBox.Rtf;
}

这段代码比较丑陋,我相信它可以得到改进和优化。但是它确实完成了应该完成的任务。


1

如果剪贴板上的RTF包含/font指令片段,那么显然这种方法无法按照您的意愿工作。这种情况非常普遍。过滤RTF片段只能通过将其粘贴到辅助RichTextBox中来实现。使用SelectionFont属性,然后将其复制回剪贴板并进行粘贴操作。或者直接这样做:

        int oldpos = richTextBox1.SelectionStart;
        richTextBox1.SelectionLength = 0;
        richTextBox1.Paste();
        int newpos = richTextBox1.SelectionStart;
        richTextBox1.SelectionStart = oldpos;
        richTextBox1.SelectionLength = newpos - oldpos;
        richTextBox1.SelectionFont = richTextBox1.Font;
        richTextBox1.SelectionStart = newpos;

1
我想提供完全相同的代码。但是,它无法正常工作,因为它还会删除加粗或斜体等修饰符! - Daniel Hilgarth
1
可以通过循环遍历具有相同字体的片段来完成。这需要逐个字符地迭代文本,直到SelectionFont发生变化。我会把这留给原帖作者。 - Hans Passant
谢谢Hans和Daniel。我不太理解最后一部分需要我遍历文本。如果我按照你发布的代码,我会在粘贴后覆盖字体(即:richTextBox1.SelectionFont = richTextBox1.Font;),这不意味着SelectionFont属性永远不会改变吗? - Hussein Khalil
随便使用任何字体都可以。关键是将粘贴的内容更改为所需的字体。 - Hans Passant
谢谢你们两个,我希望我能将两个答案都标记为被接受的答案。 - Hussein Khalil

1

我知道这个方法有些老旧;但是丹尼尔的回答对我有用,只需要将所有实例的richTextBox1.Selection替换为直接引用整个richTextBox1的字体和大小即可。在这种情况下,我粘贴的任何RTF都将继承当前richTextBox1正在使用的字体系列和字号,同时保留RTF样式。

public void SpecialPaste()
{
    var helperRichTextBox = new RichTextBox();
    helperRichTextBox.Paste();
    helperRichTextBox.SelectionStart = 0;
    helperRichTextBox.SelectionLength = 1;

Font lastFont = helperRichTextBox.SelectionFont;
int lastFontChange = 0;
for (int i = 0; i < helperRichTextBox.TextLength; ++i)
{
    helperRichTextBox.SelectionStart = i;
    helperRichTextBox.SelectionLength = 1;
    if (!helperRichTextBox.SelectionFont.Equals(lastFont))
    {
        lastFont = helperRichTextBox.SelectionFont;
        helperRichTextBox.SelectionStart = lastFontChange;
        helperRichTextBox.SelectionLength = i - lastFontChange;
        helperRichTextBox.SelectionFont = new Font(richTextBox1.Font.FontFamily, richTextBox1.Font.Size, helperRichTextBox.SelectionFont.Style);
        lastFontChange = i;
    }
}
helperRichTextBox.SelectionStart = helperRichTextBox.TextLength-1;
helperRichTextBox.SelectionLength = 1;
helperRichTextBox.SelectionFont = new Font(richTextBox1.Font.FontFamily, richTextBox1.Font.Size, helperRichTextBox.SelectionFont.Style);

richTextBox1.Rtf = helperRichTextBox.Rtf;

}


1

我知道有点晚了,但我遇到了同样的问题,这是我的解决方案(希望能帮助其他人):

首先,处理RichTextBox的KeyDown事件:

this.richTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.RichTextBoxKeyDown);

接下来,检查粘贴键事件并重新设置剪贴板文本(这就是魔法发生的地方):
     private void RichTextBoxKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.V)
            {
                try
                {
                    Clipboard.SetText(Clipboard.GetText());
                }
                catch (Exception)
                {
                }
            }
        }

解释: 首先,我要说这只是在.NET 4.0上进行测试的。假设没有修改使用的任何函数,这也适用于旧版本的.NET。
调用Clipboard.GetText()以纯文本格式返回内容(不包括RTF标记)。然后,我们通过调用Clipboard.SetText()并使用从Clipboard.GetText()获取的纯文本来更改将要粘贴的文本。现在,当事件完成并传递给控件时,它将执行从剪贴板获取最新文本(我们更改过的版本)的粘贴操作。它被包装在try/catch块中的原因是因为SetText有时会抛出异常,即使它已经成功将文本复制到剪贴板中。当然,您可以使用Clipboard提供的其他方法来获取/设置文本,这只是解决方案的基本版本。
新粘贴的文本将继承光标位置的格式,类似于手动输入到RTB中。
不幸的是,这也会删除文本的样式(加粗、着色等)。
希望这能帮助到您!

0
我尝试从Word文档中复制文本,并在运行时将其粘贴到RichTextBox中。一切都正常工作,我没有进行任何特定的调整。只是将RichTextBox拖放到窗体上,并从MS Word文档中复制格式化的文本。

嗨,感谢您的回答。粘贴功能很好用,但请尝试在Word中调整文本大小,然后将其粘贴到RichTextBox中。RichTextBox中的文本将与Word文档中的文本大小相同。我希望它与我的RichTextBox的基础字体大小相同。 - Hussein Khalil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接