Как предотвратить вставку данных изображения системного буфера обмена в WPF RichTextBox - PullRequest
2 голосов
/ 19 октября 2010

В настоящее время у меня есть некоторый код для перехвата всех событий вырезания, копирования и вставки в RichTextBox в WPF. Они предназначены для удаления всего содержимого, кроме обычного текста, и не допускают вставки, кроме простого текста (с помощью проверки методом Clipboard.ContainsText ().) Кажется, это успешно предотвращает все такие операции от внутри формы. Пользователь может копировать, вырезать и вставлять текст только с изображениями / аудио данными / случайным мусором, не разрешенным.

Однако, если я использую функцию PrintScreen и вставляю ее в один из RichTextBoxes, изображение вставляется (а не в требуемое поведение.) Если вы затем попытаетесь вставить это изображение из одного 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 (и т. Д.) По существу проверяют наличие только текста, прежде чем разрешать какие-либо операции.

Кажется, здесь работают два буфера обмена, один из которых я не ограничиваю / блокирую. Кто-нибудь знает о технических особенностях этого и о том, каким образом все действия буфера обмена (как формы, так и системы) могут быть заблокированы и эффективно настроены?

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 04 сентября 2015

На самом деле вам не нужен какой-либо взлом, например, перехват событий 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 на тот, который содержит только форматы, которые вы используете.хочу поддержать (а не полностью отменить вставку).

2 голосов
/ 19 октября 2010

Это может быть немного неумолимо для пользователя, но вы можете сделать это так же просто, как захват или очистка буфера обмена перед вставкой. Просто подключите 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();
}

Не самое удачное решение, но оно поможет.

0 голосов
/ 10 февраля 2017

Я думаю, что это, вероятно, лучший способ, если ваша цель состоит в том, чтобы просто вставить простой текст:

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;
        }            
    }
...