TX Text Control .NET for WPF

Clipboard Operations

Topic

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

MemberDoes
CopyCopies the selection to the clipboard
CutMoves the selection to the clipboard
PasteReplaces the selection with the content of the clipboard; with a ClipboardFormat value, it pastes only that format
CanCopyWhether text is selected and may be copied
CanPasteWhether the clipboard holds a format the editor can paste, and the document may be changed
GetClipboardFormatsThe 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:

  • SubmenuOpened occurs each time the menu opens, so the items reflect the selection and the clipboard at that moment. IsEnabled grays out an item that cannot be used.
  • CanCopy is false without a selection. CanEdit is false when 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 that GetClipboardFormats returns.

Values of ClipboardFormat

ValueClipboard content
TXTextControlFormatFormatted text in the internal TX Text Control format
RichTextFormatRTF
HTMLFormatHTML
PlainTextText without formatting
ImageA device-dependent or device-independent bitmap, a TIFF image or a Windows metafile
TXTextControlImageAn image with its position in the document, inline or geometrically positioned
TXTextControlTextframeA text frame with its content and position
Chart, BarcodeA 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. With ReadAndSelect, 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