Trevor Elliott
Trevor Elliott

Reputation: 11252

IDataObject.GetData() always returns null with my class

I have a class which I marked as [Serializable] that I'm trying to copy through the clipboard. Calling GetData() always returns null.

Copy code:

IDataObject dataObject = new DataObject();
dataObject.SetData("MyClass", false, myObject);
Clipboard.SetDataObject(dataObject, true);

Paste code:

if (Clipboard.ContainsData("MyClass"))
{
    IDataObject dataObject = Clipboard.GetDataObject();

    if (dataObject.GetDataPresent("MyClass"))
    {
        MyClass myObject = (MyClass)dataObject.GetData("MyClass");
        // myObject is null
    }
}

MyClass is actually a derived class. Both it and its base are flagged as [Serializable]. I tried the same code with a simple test class and it worked.

MyClass contains GraphicsPath, Pen, Brush, and arrays of value types.

Upvotes: 3

Views: 5158

Answers (2)

Deb
Deb

Reputation: 11

I had the same problem then I googled to find this link It gives you a function IsSerializable to test which portion of my class is not serializable. By using this function I found those portions ans used [Serializable] to make them serializable. Note that all structs and classes defined inside any module (like general) which the class to be serialized uses must be marked as [Serializable]. Some portion of the code cannot / should not be serialized and they should be specifically marked as [NonSerialized]. Ex: System.Data.OleDBConnection

Upvotes: 1

Robert Slaney
Robert Slaney

Reputation: 3722

The Pen class is not marked as serializable, and also inherits from MarshalByRefObject.

You will need to implement ISerializable and handle these types of objects

[Serializable]
public class MyClass : ISerializable
{
    public Pen Pen;

    public MyClass()
    {
        this.Pen = new Pen(Brushes.Azure);
    }

    #region ISerializable Implemention

    private const string ColorField = "ColorField";

    private MyClass(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");

        SerializationInfoEnumerator enumerator = info.GetEnumerator();
        bool foundColor = false;
        Color serializedColor = default(Color);

        while (enumerator.MoveNext())
        {
            switch (enumerator.Name)
            {
                case ColorField:
                    foundColor = true;
                    serializedColor = (Color) enumerator.Value;
                    break;

                default:
                    // Ignore anything else... forwards compatibility
                    break;
            }
        }

        if (!foundColor)
            throw new SerializationException("Missing Color serializable member");

        this.Pen = new Pen(serializedColor);
    }

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue(ColorField, this.Pen.Color);
    }
    #endregion
}

Upvotes: 3

Related Questions