Putting formatted text on the clipboard
22nd August 2008
Working with the Windows clipboard in managed code is both easy and hard. It’s easy because all you need to do in order to put a bit of text on the clipboard is this:
Clipboard.SetText("Put this on the clipboard");
It’s hard because you can’t just do something like this in order to get formatted text:
Clipboard.SetHtml('<a href="http://twwilliams.com/>A link</a>"');
The Windows clipboard requires content to be in special formats if you have anything other than text and the System.Windows.Forms.Clipboard class doesn’t provide any convenience methods for handling HTML. But writing your own isn’t too hard.
Mike Stall provides the solution.
In essence, you need to wrap your HTML fragment in a specially-formatted header and then put that on the clipboard.
One thing Mike doesn’t address in his sample is how to set the plain-text version of an HTML fragment so that you can still paste to places like Notepad that don’t support formatted output.
If you only set the System.Windows.Forms.DataFormats.Html part of the clipboard, when you go to Notepad and paste, you will get nothing. So you also need to set the DataFormats.Text part. But it gets a little bit more complicated because you can’t just do this:
Clipboard.SetText(htmlString, TextDataFormat.Html); Clipboard.SetText(plainTextString, TextDataFormat.Text);
If you do this, you’re setting two values to the clipboard in succession and you will only have the last one (in this case, the plain text) on the clipboard. To set both formats, you need to use a System.Windows.Forms.DataObject:
DataObject dataObj = new DataObject(); dataObj.SetData(DataFormats.Text, plainTextString); dataObj.SetData(DataFormats.Html, HtmlFragment.GetClipboardFormatted(htmlString)); Clipboard.SetDataObject(dataObj);
In this example, the HtmlFragment.GetClipboardFormatted(htmlString) is a method I adapted from Mike Stall’s example that returns the formatted string rather than putting it directly on the clipboard as in his example.
The last thing to remember about working with the clipboard: your program must run in single-threaded apartment mode so set the [STAThread] attribute.