Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#
Article

Saving and obtaining custom objects to/from Windows Clipboard

Rate me:
Please Sign up or sign in to vote.
4.90/5 (29 votes)
26 Aug 20043 min read 123.5K   53   21
The code shows how to save (and restore) an instance of your own class to clipboard.

Introduction

This article shows, how to save an instance of a custom C#.NET class (any class) to a clipboard. It explains what requirements your class has to meet, so that you can save it to the clipboard.

Background

Surprisingly, but I've found a very few materials on this topic on the Internet. There are thousands of posts like "help, when I retrieve data from clipboard, it always returns null". Most of the answers I've found make contrary statements, some of them say that "you can't save a reference-type object to a clipboard", and other crap like this.

So, colleagues, let me save your time and provide you with some info.

Serialization

Basically, serialization is a process of "saving" an object to a form, that can be transported, copied to hard disk, sent by email etc. And vice versa, deserialization is making an instance of an object from this form (for example, from a byte stream). And this is the first and the only clipboard requirement for your class. Your class has to be serializable.

To make a class serializable, you can implement a ISerializable interface, but the easiest way to make a class serializable is to mark it with the Serializable attribute. Like this:

C#
[Serializable]
public class Document
{
  public int documentID = 0;
  public string documentDescription = "";
}
// that was simple huh?

Important: please note, that if your class is derived from some base class, the base class also has to be marked as Serializable. Like this:

C#
[Serializable]
public class Document
{
  public int documentID = 0;
  public string documentDescription = "";
}
[Serializable]
public class EmailDocument : Document {
  public string subject = "";
  public string body = "";
}

Also note, that if your class has some complex private properties, that can't be serialized (or you don't want them to be serialized), you should mark such properties with [NonSerialized()] attribute like this:

C#
[Serializable]
public class Document
{
  public int documentID = 0;
  public string documentDescription = "";

  [NonSerialized]
  private System.Data.SqlClient.SqlCommand cmd;
  [NonSerialized]
  private System.Data.SqlClient.SqlConnection cn;
}

Determine if your object is serializable or not

To determine if your class is clipboard compatible, you can write a simple method IsSerializable(object obj) (see listing below). It uses a BinaryFormatter class to serialize your object to a MemoryStream. This method requires some memory, so use it only for debugging purposes, remove it from your app when finished testing. Here it is:

C#
using System.Runtime.Serialization.Formatters.Binary;
private static bool IsSerializable(object obj)
{
  System.IO.MemoryStream mem = new System.IO.MemoryStream();
  BinaryFormatter bin = new BinaryFormatter();
  try
  {
    bin.Serialize(mem, obj);
    return true;
  }
  catch(Exception ex)
  {
    MessageBox.Show("Your object cannot be serialized." + 
                     " The reason is: " + ex.ToString());
    return false;
  }
}

Clipboard Formats

Other things we have to learn is data formats. Every application stores some data to the clipboard in some data format (or in multiple data formats). There are standard formats like Text, Image, Wave Audio, HTML text etc. These formats are pre-registered on every Windows-computer. Any application "knows", what formats it "understands", so an application "knows" if the data at the clipboard can be pasted to it. An application can store some data using one of these standard formats, or register its own data format.

.NET framework Clipboard class

Accessing the Clipboard and storing data there with a Windows application is made possible through the use of the SetDataObject() method of a Clipboard class, which stores the data on the Clipboard using the IDataObject interface. Retrieving data from the Clipboard is also done through the IDataObject interface.

Copy to clipboard

To save your custom object to a clipboard, you need to register your custom clipboard format (if it's not already registered), create an instance of a DataObject filled with your data, and pass this instance to a ClipBoard.SetDataObject() method. To register your own custom data format, all you have to do is to think up a name for your data format! And then call a static member DataFormats.GetFormat(). Personally, I think that the best name for a new data format is a full name of its type.

Just look at the code. I've added CopyToClipboard() method to my above Document class:

C#
[Serializable]
public class Document
{
  public int documentID = 0;
  public string documentDescription = "";

  [NonSerialized]
  private System.Data.SqlClient.SqlCommand cmd;
  [NonSerialized]
  private System.Data.SqlClient.SqlConnection cn;
  
  public void CopyToClipboard()
  {
    //register my custom data format with Windows
    //or get it if it's already registered
    DataFormats.Format format = 
         DataFormats.GetFormat(typeof(Document).FullName);

    //now copy to clipboard
    IDataObject dataObj = new DataObject();
    dataObj.SetData(format.Name, false, this);
    Clipboard.SetDataObject(dataObj, false);
    
    //that's it
  }
}

Obtain data from clipboard

First of all, before getting some data from clipboard, you have to ensure that the data format in the clipboard is compatible with your app. To do this, call GetDataPresent() method of a DataObject instance. After that, you call a GetData() method of a IDataObject interface. Here's the code, where I get my Document object from clipboard:

C#
protected static Document GetFromClipboard()
{
    Document doc = null;
    IDataObject dataObj = Clipboard.GetDataObject();
    string format = typeof(Document).FullName;
    
    if(dataObj.GetDataPresent(format))
    {
        doc = dataObj.GetData(format) as Document;
    }
    return doc;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Founder Jitbit
United Kingdom United Kingdom
I'm CEO/Founder and lead developer at Jitbit Software. My personal blog is here

Comments and Discussions

 
GeneralFields vs. properties Pin
ip25531-Aug-04 10:40
ip25531-Aug-04 10:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.