65.9K
CodeProject is changing. Read more.
Home

Copy and Paste in WPF User Control

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.31/5 (5 votes)

Jul 16, 2012

CPOL

1 min read

viewsIcon

50144

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