Clipboard Operations
The WPF TextControl shares the Windows clipboard with every other application: text copied in Word, a browser or an image editor can be pasted into it, and text copied in it can be pasted elsewhere. The keys work without code. Your code adds menu commands, pastes a single format such as plain text, and checks whether copying and pasting are possible.
The examples assume a window with a TextControl named textControl1, as built in Create Your First WPF Application. Copying acts on the current selection, which Selections and Caret Position describes.
Built-In Keys and Ribbon Buttons
Ctrl+C copies the selected text to the clipboard, Ctrl+X cuts it and Ctrl+V pastes the content of the clipboard in place of the selection; Keyboard Shortcuts lists them with the other editing keys.
A window with the WPF ribbon offers the commands in the Clipboard group of the formatting tab, which is labeled Home. Besides Cut and Copy, its Paste button has a drop-down menu with paste commands for text, plain text, images, text frames, charts, barcodes and drawings. See Built-in Ribbon Tabs.
If the clipboard offers several formats, the editor pastes the one with the most information, in this order: text frame, formatted image, formatted text in the TX Text Control format, RTF, HTML, plain text and image.
Copy, Cut and Paste in Code
| Member | Does |
|---|---|
| Copy | Copies the selection to the clipboard |
| Cut | Moves the selection to the clipboard |
| Paste | Replaces the selection with the content of the clipboard; with a ClipboardFormat value, it pastes only that format |
| CanCopy | Whether text is selected and may be copied |
| CanPaste | Whether the clipboard holds a format the editor can paste, and the document may be changed |
| GetClipboardFormats | The formats on the clipboard that the editor can paste, or null if there are none |
The following window puts an Edit menu above the editor. In MainWindow.xaml, a DockPanel holds the menu and the TextControl:
<Window x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WPF="clr-namespace:TXTextControl.WPF;assembly=TXTextControl.WPF"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_Edit" SubmenuOpened="EditMenu_SubmenuOpened">
<MenuItem x:Name="cutItem" Header="Cu_t" Click="Cut_Click" />
<MenuItem x:Name="copyItem" Header="_Copy" Click="Copy_Click" />
<MenuItem x:Name="pasteItem" Header="_Paste" Click="Paste_Click" />
<MenuItem x:Name="pastePlainTextItem" Header="Paste as Plain _Text" Click="PastePlainText_Click" />
</MenuItem>
</Menu>
<WPF:TextControl x:Name="textControl1" />
</DockPanel>
</Window>
The handlers go into MainWindow.xaml.cs. Replace SampleApp with the namespace of your project:
using System;
using System.Windows;
using TXTextControl;
namespace SampleApp;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void EditMenu_SubmenuOpened(object sender, RoutedEventArgs e)
{
// Enable only what is possible with the current selection and clipboard
copyItem.IsEnabled = textControl1.CanCopy;
cutItem.IsEnabled = textControl1.CanCopy && textControl1.CanEdit;
pasteItem.IsEnabled = textControl1.CanPaste;
// Paste(ClipboardFormat) accepts only a format the clipboard offers
ClipboardFormat[] formats = textControl1.GetClipboardFormats();
pastePlainTextItem.IsEnabled = textControl1.CanPaste && formats != null
&& Array.IndexOf(formats, ClipboardFormat.PlainText) >= 0;
}
private void Cut_Click(object sender, RoutedEventArgs e) => textControl1.Cut();
private void Copy_Click(object sender, RoutedEventArgs e) => textControl1.Copy();
private void Paste_Click(object sender, RoutedEventArgs e) => textControl1.Paste();
private void PastePlainText_Click(object sender, RoutedEventArgs e) =>
textControl1.Paste(ClipboardFormat.PlainText);
}
Run the application, copy formatted text in another application and open Edit: Paste keeps the formatting, Paste as Plain Text drops it.
The code works as follows:
SubmenuOpenedoccurs each time the menu opens, so the items reflect the selection and the clipboard at that moment.IsEnabledgrays out an item that cannot be used.CanCopyisfalsewithout a selection. CanEdit isfalsewhen the document is read-only, which rules out cutting.Paste(ClipboardFormat.PlainText)requires plain text on the clipboard. The handler looks for it in the array thatGetClipboardFormatsreturns.
Values of ClipboardFormat
| Value | Clipboard content |
|---|---|
TXTextControlFormat | Formatted text in the internal TX Text Control format |
RichTextFormat | RTF |
HTMLFormat | HTML |
PlainText | Text without formatting |
Image | A device-dependent or device-independent bitmap, a TIFF image or a Windows metafile |
TXTextControlImage | An image with its position in the document, inline or geometrically positioned |
TXTextControlTextframe | A text frame with its content and position |
Chart, Barcode | A chart or a barcode |
A "Paste Special" command follows from these values: offer the formats that GetClipboardFormats returns and call Paste with the one the user chooses.
When Copying and Pasting Is Not Allowed
The Can… properties follow the protection settings of the document:
- With EditMode set to
ReadOnly, text cannot even be selected, so nothing can be copied. WithReadAndSelect, the document permissions decide. - DocumentPermissions.AllowCopy specifies whether content may be copied to the clipboard. DocumentPermissions returns the permissions of the document.
Document Protection and Editable Regions covers both.
Delete the Selection
Clear deletes the selected text, or the character to the right of the input position when nothing is selected. The clipboard is not changed.
Paste a Word Document With Its Page Size
Pasted text flows into the pages of the current document; the page size and margins of the document it came from are not taken over. To open copied content as a document with its own page settings, read the RTF data from the WPF clipboard and load it with Load and a LoadSettings object:
private void PasteAsDocument()
{
string rtf = Clipboard.GetData(DataFormats.Rtf) as string;
if (rtf != null)
{
LoadSettings loadSettings = new LoadSettings();
textControl1.Load(rtf, StringStreamType.RichTextFormat, loadSettings);
// Take over the page size and margins of the copied document
textControl1.PageSize = loadSettings.PageSize;
textControl1.PageMargins = loadSettings.PageMargins;
}
}
Here, Clipboard and DataFormats are the classes of the System.Windows namespace. Load replaces the whole document. LoadSettings.PageSize and PageMargins return the page settings found in the data, and TextControl.PageSize and TextControl.PageMargins apply them.
Next Steps
- Undo and Redo: undo a paste.
- Drag and Drop: move text with the mouse and accept dropped files.
- Context Menus: the built-in context menu of the editor.
- Keyboard Shortcuts: all keys of the editor.