How can I copy WPF FlowDocument InlineUIContainer

2019-04-29 03:18发布

I have a WPF FlowDocument that has a few InlineUIContainers, these are simple InlineUIContainers, that contain a styled button with some text in the Button.Content. When I copy the text and InlineUIContainer containing the button from the FlowDocument to a TextBox, the button is not copied.

It is possible to somehow convert the inline button or convert the button to text in the pasted text data. I have tried using the FlowDocument.DataObject.Copying event, but I can't seem to find any good samples on how to use this or even if this is the right direction.

Thank you

1条回答
beautiful°
2楼-- · 2019-04-29 03:46

I had the same problem and managed to get something like the following to work:

public class MyRichTextBox : RichTextBox
{
    public MyRichTextBox()
        : base()
    {
        CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                                                   new CommandBinding(ApplicationCommands.Copy, OnCopy, OnCanExecuteCopy));
    }

    private static void OnCanExecuteCopy(object target, CanExecuteRoutedEventArgs args)
    {
        MyRichTextBox myRichTextBox = (MyRichTextBox)target;
        args.CanExecute = myRichTextBox.IsEnabled && !myRichTextBox.Selection.IsEmpty;
    }

    private static void OnCopy(object sender, ExecutedRoutedEventArgs e)
    {
        MyRichTextBox myRichTextBox = (MyRichTextBox)sender;
        Clipboard.SetText(GetInlineText(myRichTextBox));
        e.Handled = true;
    }

    private static string GetInlineText(RichTextBox myRichTextBox)
    {
        StringBuilder sb = new StringBuilder();
        foreach (Block b in myRichTextBox.Document.Blocks)
        {
            if (b is Paragraph)
            {
                foreach (Inline inline in ((Paragraph)b).Inlines)
                {
                    if (inline is InlineUIContainer)
                    {
                        InlineUIContainer uiContainer = (InlineUIContainer)inline;
                        if (uiContainer.Child is Button)
                            sb.Append(((Button)uiContainer.Child).Content);
                    }
                    else if (inline is Run)
                    {
                        Run run = (Run)inline;
                        sb.Append(run.Text);
                    }
                }
            }
        }
        return sb.ToString();
    }
}

Of course this is very simplistic - you would probably create a subclass of Button and define an interface-function like "GetCopyToClipboardText" instead of having the "how to get text from a button"-code inside the richtextbox.

The example copies all text inside the richtextbox - it would be more usefull if only the selected part of the textbox was copied to the clipboard. This post gives an example of how to achive that.

查看更多
登录 后发表回答