1

I am trying to disable Copy/Paste/Cut feature in special window in xaml(WPF).

I set the PreviewKeyDown="Window_PreviewKeyDown" in properties of special window. This way any key down it will track and cancel. Below code is working fine for disallow copy & paste for outside.

private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if(Keyboard.Modifiers == ModifierKeys.Control && (e.Key == Key.C || e.Key == Key.X))
            {
                e.Handled = true;
            }
            if(Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.V)
            {
                e.Handled = true;
            }
        }

This works

Now, I would like to allow copying and pasting from within the application itself.

Is there a way to disallow outside copy pasting into an application except for what has been copied and pasted from with an application?

Community
  • 1
  • 1
Bunty Choudhary
  • 185
  • 1
  • 3
  • 11
  • You can store copied content in copy handler and restore it inside paste handler in your code. – Misaz Jul 25 '19 at 08:12
  • It would be good to know background, what exactly are you doing. I think you need custom clipboard format. – Sinatr Jul 25 '19 at 08:14
  • @Misaz Sorry I am not clearly getting you – Bunty Choudhary Jul 25 '19 at 08:16
  • @Sinatr mygoal is not allow the user to copy anything from the application to user PC and not copy paste anything from user PC into Application. But within application, the user must be allowed to copy paste information – Bunty Choudhary Jul 25 '19 at 08:18
  • @bunty-choudhary make field/property in form class and in `if` clause store copeid value into it and in `If` that you checks for paste paste value from your field/property. – Misaz Jul 25 '19 at 08:19
  • @Misaz Can you please let me know that how can I know the copied content has been from outside/Inside of the application – Bunty Choudhary Jul 25 '19 at 08:22
  • @bunty-choudhary Check for example https://stackoverflow.com/questions/7616274/change-paste-contents-in-textbox – Misaz Jul 25 '19 at 08:35
  • @Misaz I tried with store copied content in copy handler and restore it inside paste handler and it works, but problem is that we need to disallow the paste outside also. – Bunty Choudhary Jul 25 '19 at 11:25
  • @Misaz Thanks now done with it – Bunty Choudhary Jul 25 '19 at 12:48

2 Answers2

1

I was able to dig a quick solution using this answer. The idea is to restrict copy/paste to allow only application custom data format in clipboard. I have tested it with single TextBox, which only accept paste for text copied within itself, anything copied from outside is ignored.

First thing is to add command bindings to TextBox in xaml. This allows to intercept both: CTR+C/V keys and context menu clicks:

<TextBox>
    <TextBox.CommandBindings>
        <CommandBinding Command="{x:Static ApplicationCommands.Copy}"
                        CanExecute="CanCopy"
                        Executed="Copy" />
        <CommandBinding Command="{x:Static ApplicationCommands.Paste}"
                        CanExecute="CanPaste"
                        Executed="Paste" />
    </TextBox.CommandBindings>
</TextBox>

Second add handlers to code behind:

void Copy(object sender, ExecutedRoutedEventArgs e)
{
    Clipboard.SetData("My Data", ((TextBox)sender).SelectedText);
}

void CanCopy(object sender, CanExecuteRoutedEventArgs e)
{
    if (sender is TextBox textBox && textBox.SelectionLength > 0)
        e.CanExecute = true;
}

void CanPaste(object sender, CanExecuteRoutedEventArgs e)
{
    if (Clipboard.ContainsData("My Data"))
        e.CanExecute = true;
    e.Handled = true; // prevent other paste handlers
}

void Paste(object sender, ExecutedRoutedEventArgs e)
{
    (sender as TextBox).SelectedText = (string)Clipboard.GetData("My Data");
}

TODO: fix paste and refactor this into attached behavior for better reusability.

Sinatr
  • 20,892
  • 15
  • 90
  • 319
-2

Here is the answer. We need to clear the clipboard when deactivate the window and can be set the text again into clipboard while activate.

private string oldClipboardContent { get; set; } = "";

 private void Window_Activated(object sender, EventArgs e)
        {
            Clipboard.SetText(oldClipboardContent);
        }

        private void Window_Deactivated(object sender, EventArgs e)
        {
            oldClipboardContent = Clipboard.GetText();
            Clipboard.Clear();
        }
Bunty Choudhary
  • 185
  • 1
  • 3
  • 11