DISABLE ADBLOCK

ADBlock is blocking some content on the site

ADBlock errore
Results found: 

Question

I have a custom type, FooNode, defined in my C# code. I want to add an instance of that custom type to the global System.Windows.Forms.Clipboard, and then retrieve it from the clipboard again. The add seems to work, but I am not able to retrieve the instance. Upon retrieval, several exceptions print to standard output like the following:

A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in System.Windows.Forms.dll<br />(... and 9 more just like above)


The result of the retrieval is a null reference. There is no crash or halt. The above exceptions are being dealt with internally; I am not able to catch them. The problem is not with the DataObject itself, because I can retrieve my FooNode from it. I just can't retreive my FooNode from the clipboard's DataObject.

I am able to add and then retreive other types of objects to the system clipboard, such as strings and System.Guid. Why can I not retrieve an object of my custom type?

Following is my test code. Call FooTest.Test() to run.

using System;
using System.Diagnostics;
using System.Windows.Forms;

public class FooNode
{
  private Guid m_Guid;
  private string m_Name = String.Empty;

  public FooNode( )
  {
    m_Guid = Guid.NewGuid();
    m_Name = "Foo";
  }

  public Guid Guid
  {
    get { return m_Guid; }
    set { m_Guid = value; }
  }

  public string Name
  {
    get { return m_Name; }
    set { m_Name = value; }
  }
}

public class FooTest
{
  // Entry point for test of using system clipboard.
  public static void Test( )
  {
    FooNode fooNode = new FooNode();

    // Add a FooNode to the system clipboard.
    DataObject dob = new DataObject( fooNode );
    dob.SetData( typeof( Guid ), fooNode.Guid );
    dob.SetData( DataFormats.StringFormat, fooNode.Guid.ToString() );
    Clipboard.SetDataObject( dob );

    // Retrieve the FooNode from the system clipboard.
    // *** Notice that the returned object is null. ***
    object raw = Clipboard.GetDataObject().GetData( typeof( FooNode ) );

    // Demonstrate what can and cannot be retrieved from the clipboard.
    Spam( Clipboard.GetDataObject(), new Type[] { typeof( FooNode ), typeof( Guid ) } );
  }

  public static void Spam( IDataObject dob, Type[] types )
  {
    Debug.WriteLine( dob );
    Debug.Indent();

    Debug.WriteLine( "Data formats:" );
    Debug.Indent();
    string[] formatNames = dob.GetFormats( true );
    foreach ( string name in formatNames )
    {
      Debug.WriteLine( name );
    }
    Debug.Unindent();

    // Test if I can access the data by format name.
    foreach ( string name in formatNames )
    {
      if ( dob.GetDataPresent( name ) )
      {
        Debug.WriteLine( String.Format( "Present as format=\"{0}\"", name ) );
        Debug.Indent();
        object raw = dob.GetData( name );
        Debug.WriteLine( String.Format( "raw={0}", raw != null ? raw : "null" ) );
        Debug.Unindent();
      }
    }

    // Test if I can access the data by type.
    if ( types != null )
    {
      foreach ( Type type in types )
      {
        if ( dob.GetDataPresent( type ) )
        {
          Debug.WriteLine( String.Format( "Present as type={0}", type ) );
          Debug.Indent();
          object raw = dob.GetData( type );
          Debug.WriteLine( String.Format( "raw={0}", raw != null ? raw : "null" ) );
          Debug.Unindent();
        }
      }
    }

    Debug.Unindent();
  }
}


modified on Monday, May 18, 2009 8:21 PM

Solution

Hi,

I'm no expert in this matter, but I doubt your object makes it to the Clipboard. I have a hunch you need a [Serializable] for your FooNode class. Also you may want to add ",true" to Clipboard.SetDataObject() to make your object survive your app.

:)

If you like, leave us your opinion

Was the article helpful and is it translated correctly?

Licensed under: CC-BY-SA with attribution
Not affiliated with CodeProject