Skip to main content

ClientClipboard

ClientClipboard gives server code access to the clipboard of the user's machine, through the browser's Clipboard API. With it you can:

  • write text or images to the clipboard, for Copy to clipboard buttons;
  • read text or images from it, for Paste buttons, or to import an image copied from another program;
  • get an event when the user cuts, copies or pastes anywhere in the application.

System.Windows.Forms.Clipboard and friends work on the server's clipboard, which is no use in a web application. Use this extension whenever you mean the user's clipboard.

Installation​

Add the Wisej-4-ClientClipboard package to your Wisej.NET project:

dotnet add package Wisej-4-ClientClipboard

The package targets .NET Framework 4.8 and .NET 8 or later. There's nothing to drop on a page: ClientClipboard is a static class that you call directly.

Browser requirements
  • The Clipboard API is available only in a secure context: HTTPS, or http://localhost during development.
  • Browsers protect the clipboard. Reading asks the user for permission (clipboard-read) or shows a Paste prompt, and the call fails if the user refuses. Writing normally works only in response to a user action, such as a button click.
  • Support differs between browsers, especially for images and for reading. Check the browser compatibility table for the browsers you support.

Getting started​

A Copy and a Paste button for a text box:

using Wisej.Ext.ClientClipboard;

private async void buttonCopy_Click(object sender, EventArgs e)
{
await ClientClipboard.WriteTextAsync(this.textBox1.Text);
AlertBox.Show("Copied to the clipboard.");
}

private async void buttonPaste_Click(object sender, EventArgs e)
{
try
{
this.textBox1.Text = await ClientClipboard.ReadTextAsync();
}
catch (Exception)
{
AlertBox.Show("Clipboard access was denied.", MessageBoxIcon.Warning);
}
}

Text​

MethodWhat it does
WriteTextAsync(text)Writes text. The task completes once the browser has updated the clipboard.
WriteText(text)Writes text, fire-and-forget.
WriteText(text, callback)Writes text and calls callback once the clipboard is updated.
ReadTextAsync()Returns the clipboard text, or an empty string when the clipboard is empty or holds no text.
ReadText(callback)The same, but delivers the text to callback.

Images​

Images travel as System.Drawing.Image objects, so they go straight into a PictureBox or into your own image processing:

// Paste an image copied from another program.
private async void buttonPasteImage_Click(object sender, EventArgs e)
{
var image = await ClientClipboard.ReadImageAsync();
if (image != null)
this.pictureBox1.Image = image;
else
AlertBox.Show("There's no image on the clipboard.");
}

// Copy the image in the PictureBox, as PNG.
private async void buttonCopyImage_Click(object sender, EventArgs e)
{
await ClientClipboard.WriteImageAsync(this.pictureBox1.Image);
}
MethodWhat it does
ReadImageAsync() / ReadImage(callback)Returns the PNG image on the clipboard, or null when there isn't one.
WriteImageAsync(image)Writes image as PNG.
WriteImageAsync(image, format)Writes image encoded in format.
WriteImage(image, callback)Writes image and calls the optional callback once the clipboard is updated.
tip

Browsers reliably support only image/png on the clipboard. Keep the default PNG unless you know the target browsers accept the format you pick.

The ClipboardChange event​

ClipboardChange fires on the server when the user cuts, copies or pastes in the browser with the keyboard or the browser menu. Its ClientClipboardEventArgs tell you what happened:

PropertyWhat it holds
TypeCut, Copy or Paste.
TargetThe control that had the focus, or null. It's also passed as sender.
ContentThe pasted text. The browser provides it only for Paste.
public Page1()
{
InitializeComponent();

ClientClipboard.ClipboardChange += ClientClipboard_ClipboardChange;
this.Disposed += (s, e) => ClientClipboard.ClipboardChange -= ClientClipboard_ClipboardChange;
}

private void ClientClipboard_ClipboardChange(object sender, ClientClipboardEventArgs e)
{
// Only react to clipboard actions on this page's controls.
if (e.Target == null || e.Target.TopLevelControl != this)
return;

if (e.Type == ClientClipboardChangeType.Paste)
this.labelStatus.Text = $"Pasted {e.Content?.Length ?? 0} characters into {e.Target.Name}.";
}
ClipboardChange is a static event

ClipboardChange is a static event, so it's shared by every session in the application process, not just the current user's. Each handler you attach receives clipboard actions from all users, so:

  • always detach the handler when its page or form is disposed, as above. Otherwise the handlers of closed pages pile up and keep those objects alive;
  • in the handler, ignore events whose Target doesn't belong to the object that attached it.

API reference​