Copy and Paste in WPF User Control






4.31/5 (5 votes)
Preparing a WPF user control to make it accept clipboard commands
Introduction
This is something that kept me wondering for quite a while when I was trying to create a user control which was able to receive clipboard commands by itself. The base XAML setup was straightforward:
<UserControl x:Class="UserControlCommands.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
>
<UserControl.CommandBindings>
<CommandBinding Command="Paste" Executed="CommandBinding_PasteExecuted"/>
<CommandBinding Command="Copy" Executed="CommandBinding_CopyExecuted"/>
</UserControl.CommandBindings>
</UserControl>
Well, nothing happened. The commandbinding
s would not fire because commands are
only routed to UI elements that have the focus. And as you can see, there's nothing
inside the usercontrol
that itself would be
able to gain the focus (e.g. a TextBox
object).
The first tip I found on this topic was to set the user control
attribute Focusable="true"
. This by itself wasn't helpful, the user control
would still not gain the focus when clicking into it. After adding IsTabStop="true"
, I was at least able to tab into the user control - and now the events would fire on CTRl+C or
CTRL+V without any more effort (Copy
and Paste
are enumerators
of the ApplicationCommands
enumeration and therefore the application is
able to raise them automatically).
However, this still is not sufficient. I wanted to make the user control to gain the focus by mouse click and then be able to paste information to it, thinking there must be some attribute or something that can be set in XAML. It turned out there is not. However I found the following thread on exactly the opposite topic:
Though I did not like this (thinking there must be some way to do this entirely in XAML), I gave in and added a MouseDown
event calling this.Focus()
. And then there was only one last step necessary: A UI element needs a background to receive mouse
clicks, so I set background="aquamarine"
.
Finally. Here's the complete sample:
XAML
<UserControl x:Class="UserControlCommands.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
IsTabStop="True"
MouseDown="UserControl_MouseDown"
Focusable="True"
Background="Aquamarine"
>
<UserControl.CommandBindings>
<CommandBinding Command="Paste" Executed="CommandBinding_Executed"/>
<CommandBinding Command="Copy" Executed="CommandBinding_Executed"/>
</UserControl.CommandBindings>
</UserControl>
Code Behind
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace UserControlCommands
{
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Clipboard operation occured!");
}
private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
{
this.Focus();
}
}
}