4

I have 2 controls one one form: list and a tree (specific type names are irrelevant).

In the list control I execute DoDragDrop method. As the first argument I pass an object which was data bound to that row. The object implements a specific interface and is marked with Serializable attribute.

What I want is to retreive that object in DragEnter/DragDrop event handler of the tree control. I'm using the following code:

void TreeControlDragEnter(object sender, DragEventArgs e)
{
    var formats = e.Data.GetFormats();
    var data = e.Data.GetData(typeof (IFoo));
}

Unfortunately, in result data is null and formats is an one-element array which holds the name of the specific type (implementing IFoo). I assume that I would have to pass exact type name to GetData to retreve the object, but it's not possible as it is a private class.

Is there a way to get the object by its interface?

2 Answers 2

3

You have to provide the same type as the class that was serialized in the first place. You cannot use an interface or base class of the serialized class because then more than one of the formats might match it and it would not know which one to deserialize. If you have several classes that all implement IFoo and there is an instance of each inside the data object then asking for IFoo would be ambiguous. So you must ask for the exact type that was serialized into the data object.

This means you should not place classes into the data object that cannot be deserialized because they are private at the other end.

Sign up to request clarification or add additional context in comments.

Comments

0

Old question, but for anyone who stumbles across this issue and looking for a general working solution:

You can build a wrapper class that holds a reference to the interface object and use that as drag-drop data:

public class DragDropObject<T>
{
    public readonly T Value;
    public DragDropObject(T value)
    {
        Value = value;
    }
}

and the use it


// start dragging object (e.g. from ListView)
protected override void OnItemDrag(ItemDragEventArgs e)
{
    base.OnItemDrag(e);
    IFoo target = GetMyTarget();
    var data = new DragDropObject<IFoo>(target);
    DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Move);
}

// drag logic
void TreeControlDragEnter(object sender, DragEventArgs e)
{
    if(e.Data.GetDataPresent(typeof(DragDropObject<IFoo>)))
    {
        var data = e.Data.GetData(typeof(DragDropObject<IFoo>));
        var draggedObject = (data as DragDropObject<IFoo>).Value;
        // ...
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.