You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF RichTextBox包含Run与InlineUIContainer时的复制粘贴功能实现问题

WPF RichTextBox包含Run与InlineUIContainer时的复制粘贴功能实现问题

我先还原下你的场景:你在WPF里创建了一个带有InlineUIContainer的RichTextBox,代码如下:

<RichTextBox x:Name="RichTextBox"
             IsDocumentEnabled="True"
             AutoWordSelection="True"
             IsInactiveSelectionHighlightEnabled="True">
    <FlowDocument>
        <Paragraph>
            <InlineUIContainer>
                <TextBlock Text="Sample"/>
            </InlineUIContainer>
        </Paragraph>
    </FlowDocument>
</RichTextBox>

你想要实现三个核心功能:

  • 复制当前RichTextBox里的选中内容,粘贴到同一个RichTextBox中
  • 从一个RichTextBox复制选中内容,粘贴到同一应用内的另一个RichTextBox
  • 复制RichTextBox的选中内容到剪贴板并保留纯文本格式,能直接粘贴到记事本这类纯文本工具里

你提到遇到了问题:当输入普通文本后尝试复制整个内容时,出现了异常(大概率是InlineUIContainer这类UI元素导致默认复制逻辑失效,要么复制不到容器里的文本,要么粘贴后格式乱掉)

解决方案思路

默认的RichTextBox复制粘贴逻辑对InlineUIContainer这类内嵌UI元素支持很差,因为它本质是UI控件而非文本内容,所以我们需要自定义复制和粘贴的事件处理逻辑,分别处理纯文本和富文本场景。

1. 自定义复制逻辑(兼顾纯文本和富文本)

在RichTextBox的Copy事件里,我们需要手动提取选中区域的所有文本(包括InlineUIContainer里TextBlock的内容),同时保留富文本格式,这样既能满足粘贴到记事本的需求,也能支持跨RichTextBox的富文本粘贴。

后台C#代码示例:

private void RichTextBox_Copy(object sender, RoutedEventArgs e)
{
    var richTextBox = sender as RichTextBox;
    if (richTextBox == null || richTextBox.Selection.IsEmpty)
        return;

    // 提取纯文本
    string plainText = GetPlainTextFromSelection(richTextBox.Selection);
    // 提取富文本XAML格式内容
    string rtfXaml = GetXamlFromSelection(richTextBox.Selection);

    // 清空剪贴板,同时添加纯文本和富文本格式
    Clipboard.Clear();
    Clipboard.SetText(plainText, TextDataFormat.Text);
    Clipboard.SetText(rtfXaml, TextDataFormat.Xaml);

    // 标记事件已处理,避免默认逻辑干扰
    e.Handled = true;
}

// 从选中区域提取纯文本的方法
private string GetPlainTextFromSelection(TextSelection selection)
{
    StringBuilder sb = new StringBuilder();
    // 遍历选中段落内的所有Inline元素
    foreach (var inline in selection.Start.Paragraph.Inlines)
    {
        if (inline is Run run)
        {
            sb.Append(run.Text);
        }
        else if (inline is InlineUIContainer container)
        {
            if (container.Child is TextBlock tb)
            {
                sb.Append(tb.Text);
            }
        }
    }
    // 注:如果需要精确处理部分选中的文本,可以通过Selection.Start/End的位置截取,这里简化为获取整个段落文本
    return sb.ToString();
}

// 从选中区域提取富文本XAML的方法
private string GetXamlFromSelection(TextSelection selection)
{
    StringWriter sw = new StringWriter();
    XamlWriter.Save(selection, sw);
    return sw.ToString();
}

2. 自定义粘贴逻辑(区分富文本和纯文本场景)

在RichTextBox的Paste事件里,我们先判断剪贴板里是否有富文本XAML(来自同应用的RichTextBox),有的话就插入富文本;如果只有纯文本,就插入纯文本Run。

后台C#代码示例:

private void RichTextBox_Paste(object sender, RoutedEventArgs e)
{
    var richTextBox = sender as RichTextBox;
    if (richTextBox == null) return;

    // 优先处理同应用的富文本粘贴
    if (Clipboard.ContainsText(TextDataFormat.Xaml))
    {
        string xaml = Clipboard.GetText(TextDataFormat.Xaml);
        StringReader sr = new StringReader(xaml);
        var newInlines = XamlReader.Load(sr) as InlineCollection;
        if (newInlines != null)
        {
            foreach (var inline in newInlines)
            {
                richTextBox.Selection.Insert(inline);
            }
        }
        e.Handled = true;
    }
    // 处理外部纯文本粘贴
    else if (Clipboard.ContainsText(TextDataFormat.Text))
    {
        string plainText = Clipboard.GetText(TextDataFormat.Text);
        richTextBox.Selection.Text = plainText;
        e.Handled = true;
    }
}

3. 绑定事件到RichTextBox

记得在XAML里给RichTextBox绑定这两个事件:

<RichTextBox x:Name="RichTextBox"
             IsDocumentEnabled="True"
             AutoWordSelection="True"
             IsInactiveSelectionHighlightEnabled="True"
             Copy="RichTextBox_Copy"
             Paste="RichTextBox_Paste">
    <!-- 原有内容 -->
</RichTextBox>

补充说明

  • 如果你需要精确处理部分选中的文本(而非整个段落),可以通过Selection.Start和Selection.End的位置来截取文本,核心思路还是遍历选中范围内的所有Inline元素提取内容。
  • 跨RichTextBox粘贴时,因为保存了富文本XAML,粘贴后会完整保留原有的InlineUIContainer结构,和原内容一致。
  • 复制到剪贴板的纯文本可以直接粘贴到记事本、Word等任何支持纯文本的工具里。

备注:内容来源于stack exchange,提问作者why stuff works

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 09:50:28