如何在使用CopyingHandler时处理Cut

时间:2017-07-14 17:03:48

标签: c# wpf

我有一些代码用于改变剪切/复制时剪贴板中的内容,它适用于复制,但我无法使Cut工作。

在xaml中,我定义了一个名为rtbEditor的RichTextBox,在Loaded事件中,我设置了CopyingHandler:

DataObject.AddPastingHandler(rtbEditor, new DataObjectPastingEventHandler(OnPaste));
DataObject.AddCopyingHandler(rtbEditor, new DataObjectCopyingEventHandler(OnCopy));

OnCopy是(简化):

private void OnCopy(object sender, DataObjectCopyingEventArgs e)
{
    // Expand the selection include whole paragraphs only:
    TextPointer newStart = rtbEditor.Selection.Start.Parapgraph.ContentStart;
    TextPointer newEnd = rtbEditor.Selection.End.Paragraph.ContentEnd;
    rtbEditor.Selection.Select(newStart, newEnd);

    // copy the selected text
    TextRange range = new TextRange(rtbEditor.Selection.Start, rtbEditor.Selection.End);
    Clipboard.SetText(range.Text);

    e.CancelCommand();
}

这对复制产生了奇迹,但是我遇到了使Cut工作的问题。

我尝试使用rtbEditor.Selection.Select()扩展选择,就是这样,但是在调用CopyingHandler时已经填充了包含复制数据的DataObject,因此更改选择不会。 t更改将放置在剪贴板中的内容。 (我仍然这样做是为了向用户提供他们的选择已经扩展的视觉反馈)

如果我删除e.CancelCommand(),那么剪切将正确删除文本,但只删除最初选择的文本而不是扩展选择,剪贴板将只包含最初选择的文本,而不是扩大的选择。我假设因为命令没有被取消,当剪切命令完成时,我的Clipboard.SetText()会立即被DataObject的内容覆盖。

我也无法在发件人或DataObjectCopyingEventArgs中找到任何可以区分此事件是Cut事件还是Copy事件的内容,因此如果文本是Cut,我可以让我的代码删除该文本。

有没有办法在这里区分切割和复制,我没有看到?或者是否有一些我可以在此过程中加入的事件? MSDN表示,当复制操作完成转换所选内容时,CopyingHandler会发生..."。但我无法找到复制操作开始之前发生的任何事件。或者我是否需要以完全不同的方式处理这个问题?

我在How to override copy and paste in richtextbox的评论中发现了一个类似的问题,但在那里没有答案

2 个答案:

答案 0 :(得分:1)

以下是我最终解决问题的方法。我发现this page在执行之前描述了拦截命令。 (在Make WPF textbox as cut, copy and paste restricted)的答案中也提到了

在XAML中,我退出了RichTextBox,为CommandManager.PreviewExecuted添加了一个事件:

<RichTextBox Name="rtbEditor" ... CommandManager.PreviewExecuted="rtbEditor_PreviewExecuted" >
每当任何命令即将在rtbEditor上执行时,都会调用

rtbEditor_PreviewExecuted。我拦截剪切和复制事件并将我的逻辑放在那里以将选择扩展到仅段落,并在我的MainWindow类中添加一个bool标志来标记传入事件是剪切还是复制。

private void rtbEditor_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
{
    if (e.Command == ApplicationCommands.Copy)
    {
        ExpandSelectionForCopy();
        mHandlingCutAction = false;
    }
    else if( e.Command == ApplicationCommands.Cut )
    {
        ExpandSelectionForCopy();
        mHandlingCutAction = true;
    }
}

这允许我在内置的剪切/复制逻辑到达之前更改RichTextBox中的选择,因此在调用CopyingHandler时,已经扩展了选择并且正确填充了DataObject。

特殊处理的额外逻辑仍然可以添加到CopyingHandler,使用mHandlingCutAction标志来判断它是剪辑还是复制动作。

答案 1 :(得分:0)

您可以使用CommandBindings

this.RichTextBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, this.RichTextBoxCutEvent));
this.RichTextBox.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, this.RichTextBoxCopyEvent));

private void RichTextBoxCutEvent(object sender, ExecutedRoutedEventArgs e)
{
    // The cut actions
}

private void RichTextBoxCopyEvent(object sender, ExecutedRoutedEventArgs e)
{
    // The copy actions
}