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();
}
}
}