【问题标题】:How can I prevent system clipboard image data being pasted into a WPF RichTextBox如何防止系统剪贴板图像数据被粘贴到 WPF RichTextBox
【发布时间】:2011-04-27 13:40:12
【问题描述】:

我目前有一些代码可以将所有剪切、复制和粘贴事件拦截到 WPF 中的 RichTextBox 中。这些旨在去除除纯文本之外的所有内容,并且除了纯文本外不允许粘贴(通过使用检查 Clipboard.ContainsText() 方法。)这似乎成功地防止了所有此类操作 inside em> 表格。用户只能复制、剪切和粘贴文本,不允许使用图像/音频数据/随机垃圾。

但是,如果我使用 PrintScreen 函数并将其粘贴到其中一个 RichTextBox 中,则图像将被粘贴(不是想要的行为。)如果您尝试将此图像从一个 RichTextBox 粘贴到另一个,它就赢了'不让你(期望的行为)。

我当前覆盖的命令是使用

// Command handlers for Cut, Copy and Paste commands.
            // To enforce that data can be copied or pasted from the clipboard in text format only.
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Copy, new ExecutedRoutedEventHandler(OnCopy), 
                new CanExecuteRoutedEventHandler(OnCanExecuteCopy)));
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Paste, new ExecutedRoutedEventHandler(OnPaste), 
                new CanExecuteRoutedEventHandler(OnCanExecutePaste)));
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Cut, new ExecutedRoutedEventHandler(OnCut), 
                new CanExecuteRoutedEventHandler(OnCanExecuteCut)));

OnCopy (etc) 方法在允许任何操作之前基本上检查是否只有文本存在。

这里似乎有两个剪贴板在工作,其中一个我没有限制/锁定。有谁知道这方面的技术细节,以及可以有效锁定和自定义所有剪贴板活动(表单和系统)的任何方式?

提前致谢。

【问题讨论】:

    标签: c# wpf richtextbox clipboard


    【解决方案1】:

    这对用户来说可能有点难以原谅,但您可以像在粘贴之前劫持和清除剪贴板一样简单地做到这一点。只需挂上 PreviewKeyDown(因为在 KeyUp 上它已经被插入),如果我们有图像并且按 Ctrl+V,则清除剪贴板:

    public Window1()
    {
        InitializeComponent();
    
        _rtf.PreviewKeyDown += OnClearClipboard;
    }
    
    private void OnClearClipboard(object sender, KeyEventArgs keyEventArgs)
    {
        if (Clipboard.ContainsImage() && keyEventArgs.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) != 0)
            Clipboard.Clear();
    }
    

    不是最巧妙的解决方案,但它可以解决问题。

    【讨论】:

    • 可能是一个愚蠢的问题,但这只会影响程序的按键,还是会影响系统其余部分的所有按键组合?我只是不想意外破坏用户在系统其余部分上的工作! :)
    • 用这种方法进行了实验,效果很好!我没想过从这个角度接近它,所以谢谢你:) 保留我的方法,因为它有助于按照我的意愿格式化文本,但你的建议解决了我遇到的最后一个问题。再次干杯!
    • 很高兴为您提供帮助!它将以这样的方式影响系统,如果您尝试将打印屏幕图像粘贴到 rtf 中,它将丢失,否则,只要您仅在 rtf 上捕获 previewkeydown 它应该只只要您的 RTF 框聚焦,请执行此操作。如果您的窗口根本没有聚焦,我保证它不会捕获事件。
    【解决方案2】:

    实际上,您不需要任何技巧,例如捕获 KeyDown 事件(这不会阻止通过上下文菜单粘贴或拖放)。有一个特定的附加事件:DataObject.Pasting

    XAML:

    <RichTextBox DataObject.Pasting="RichTextBox1_Pasting" ... />
    

    代码隐藏:

        private void RichTextBox1_Pasting(object sender, DataObjectPastingEventArgs e)
        {
            if (e.FormatToApply == "Bitmap")
            {
                e.CancelCommand();
            }
        }
    

    它可以防止所有形式的粘贴(Ctrl-V,右键单击 -> 粘贴,拖放)。

    如果你想比这更聪明,你也可以将 DataObject 替换为只包含你想要支持的格式的数据对象(而不是完全取消粘贴)。

    【讨论】:

    • 您也可以执行e.FormatToApply = DataFormats.Text; 之类的操作(这会将粘贴限制为未格式化的文本)
    【解决方案3】:

    如果您的目标只是允许粘贴纯文本,我认为这可能是一种更好的方法:

    private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.V)
            {
                if (Clipboard.GetData("Text") != null)
                    Clipboard.SetText((string)Clipboard.GetData("Text"), TextDataFormat.Text);
                else
                    e.Handled = true;
            }            
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多