0

I want to prevent users from copying content from a column in my WPF DataGrid, which I've defined as a DataGridTextColumn

Setting ClipboardContentBinding="{x:Null}" has not worked, which to me is the most obvious way to prevent any content from being copied.

<DataGrid.Columns>
    <DataGridTextColumn Header=Field"
                        Binding="{Binding Name}"
                        ClipboardContentBinding="{x:Null}" />
</DataGrid.Columns>

I expect the output to be string.empty (or not even be included in the ClipboardContents) since the ClipboardContentBinding is set to null. Instead, it's actually copying the Name.

Edit 01: I tried: ClipboardContentBinding="{x:Static Binding.DoNothing}" but that didn't work. I get an exception: System.ArgumentException: Object of type 'MS.Internal.NamedObject' cannot be converted to type 'System.Windows.Data.BindingBase'.

What does work, is setting a binding to a path that will fail. For example:

ClipBoardContentBinding="{Binding InvalidPath}" where InvalidPath does not exist on the object that's being bound... Is there a better way than relying on a magic-string path?

  • This might help: https://stackoverflow.com/questions/12780961/disable-copy-and-paste-in-datagridview – Sach Sep 06 '19 at 18:07
  • @Sach, I'm not using Windows Forms, but WPF. – lavantgarde Sep 06 '19 at 18:15
  • This is not the exact answer, it's a point in the right direction. Take a look at that accepted answer, suppressing keypresses might still work for you. – Sach Sep 06 '19 at 18:35
  • This will work but it prevents the column from being edited. You can set the column's `IsReadOnly` to true. If you need to be able to edit, then, I think, you will need to provide a `DataTemplate` using the column's `CellStyle` property. And then use Sach's suggestion to disable some operations on the `TextBox` – Jeff Sep 07 '19 at 01:05

2 Answers2

0

There is another way to disable copy by restricting copy command in CommandManager.PreviewExecuted event.

XAML

<DataGridTextColumn Header=Field" Binding="{Binding Name}" >
    <DataGridTextColumn.EditingElementStyle>
        <Style TargetType="{x:Type TextBox}">
            <EventSetter Event="CommandManager.PreviewExecuted" Handler="textBox_PreviewExecuted"/>
        </Style>
    </DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>

Code Behind

private void textBox_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
{
    if (e.Command == ApplicationCommands.Copy)
    {
        e.Handled = true;
    }
}
Wil Liam Yap
  • 191
  • 1
  • 7
0

You can accomplish what you want with the following.

Include namespace xmlns:sys="clr-namespace:System;assembly=mscorlib"

Define an empty string resource:

    <UserControl.Resources>
        <x:Static x:Key="stringEmpty" Member="sys:String.Empty" />
    </UserControl.Resources>

Reference the resource as Source instead of as Path:

<DataGridTextColumn Binding="{Binding Key}" ClipboardContentBinding="{Binding Source={StaticResource ResourceKey=stringEmpty}}" />