Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Drag n drop treeview Nodes between two different applications

Drag n drop treeview Nodes between two different applications

Scheduled Pinned Locked Moved C#
csharpjavajsonhelpquestion
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    misterbear
    wrote on last edited by
    #1

    I'm having some trouble implementing drag & drop between two treeviews in two different winform applications. It works just fine between two treeviews in the same application though. What I do is this: private void OnDragDrop(object sender, System.Windows.Forms.DragEventArgs e) { ... if (e.Data.GetDataPresent(System.Type.GetType("MyNameSpace.MyTreeNode2"))) { data = (MyTreeNode2)e.Data.GetData(System.Type.GetType("MyNameSpace.MyTreeNode2")); if (data != null) MyTreeNode2 newFolder = (MyTreeNode2)data.Clone(); ... } (The MyTreeNode2 class is inherited from the standard TreeNode class, adding only some extra properties) This will work fine when doing it with strings, probably since the format for strings is well understood or something while the format of my treenode object is not so easily shared between applications. Do I need to implement some kind of serialization stuff for my object for this to work, and pass the string? I know that there are a couple of predefined data formats available, but in java with WFC (which is where I've just this method before and it worked better I used the object type DataFormats.CF_WFCOBJECT and it worked fine. Is there a corresponding solution implemented in .NET/C#? (It works for a single child node in my treeview, but not for a folder with child elements...) Can anybody help me?

    H 1 Reply Last reply
    0
    • M misterbear

      I'm having some trouble implementing drag & drop between two treeviews in two different winform applications. It works just fine between two treeviews in the same application though. What I do is this: private void OnDragDrop(object sender, System.Windows.Forms.DragEventArgs e) { ... if (e.Data.GetDataPresent(System.Type.GetType("MyNameSpace.MyTreeNode2"))) { data = (MyTreeNode2)e.Data.GetData(System.Type.GetType("MyNameSpace.MyTreeNode2")); if (data != null) MyTreeNode2 newFolder = (MyTreeNode2)data.Clone(); ... } (The MyTreeNode2 class is inherited from the standard TreeNode class, adding only some extra properties) This will work fine when doing it with strings, probably since the format for strings is well understood or something while the format of my treenode object is not so easily shared between applications. Do I need to implement some kind of serialization stuff for my object for this to work, and pass the string? I know that there are a couple of predefined data formats available, but in java with WFC (which is where I've just this method before and it worked better I used the object type DataFormats.CF_WFCOBJECT and it worked fine. Is there a corresponding solution implemented in .NET/C#? (It works for a single child node in my treeview, but not for a folder with child elements...) Can anybody help me?

      H Offline
      H Offline
      Heath Stewart
      wrote on last edited by
      #2

      Yes, you'll need to marshal the data for transport across application boundaries. The Marshal class may be of some help. Perhaps define a struct or something easy to marshal, fill that with information from the TreeNode, marshal it as an IntPtr or something (declaring it in global memory, for example), and then pack that in the DataObject. That would probably be the easiest solution. The way you're doing it now would work within the instance of the application. Also, the format must be the same. So unless these two applications are sharing the assembly that defines your MyNameSpace.MyTreeNode2 class, then you need to just specify a string (maybe something like "MyNameSpace.MyTreeNode2" instead of Type.GetType("MyNameSpace.MyTreeNode2"), which - defined in different assemblies - would yield a different type string).

      Microsoft MVP, Visual C# My Articles

      M 1 Reply Last reply
      0
      • H Heath Stewart

        Yes, you'll need to marshal the data for transport across application boundaries. The Marshal class may be of some help. Perhaps define a struct or something easy to marshal, fill that with information from the TreeNode, marshal it as an IntPtr or something (declaring it in global memory, for example), and then pack that in the DataObject. That would probably be the easiest solution. The way you're doing it now would work within the instance of the application. Also, the format must be the same. So unless these two applications are sharing the assembly that defines your MyNameSpace.MyTreeNode2 class, then you need to just specify a string (maybe something like "MyNameSpace.MyTreeNode2" instead of Type.GetType("MyNameSpace.MyTreeNode2"), which - defined in different assemblies - would yield a different type string).

        Microsoft MVP, Visual C# My Articles

        M Offline
        M Offline
        misterbear
        wrote on last edited by
        #3

        Isn't it possible to serialize the raw object data from memory into a binary data format and just transport that? If I just define the MyTreeNode2 class as serializable with the [Serializable] attribute before the class definition and then I should be able to Serialize it into a byte array or something right? And that should be no problem to marshal I reckon... From what I could conclude there is built-in support for this type of binary serialization and deserialization, (BinaryFormatter class) which should mean that I should be able to use this method without a problem to transport an object.. So, if my thinking is right, can you tell me what's wrong with this? All I know is it doesn't do what I want it to... (code handling start drag event) // Create a formatter object IFormatter formatter = new BinaryFormatter(); // Create a memoryStream MemoryStream ms = new MemoryStream(); // Serialize the object (here of type MyNameSpace.MyTreeNode2) into the memory stream using the binary formatter formatter.Serialize(ms, draggedItem); // Put the byte array from the memory stream into a data object and specify the format // type to be of type "MyNameSpace.MyTreeNode2" DataObject dObj = new DataObject( "MyNamespace.MyTreeNode2", ms.GetBuffer() ); selectedTreeView.DoDragDrop( dObj, DragDropEffects.All ); and here is what I want to use on the receiving side. But it doesn't work, the method actually returns after the last line (data = ...) without even continuing execution of the remaining part of the method, or at least the debug stepper of VS won't continue past this point. (Why does this happen?) (code for handling drop event) // check the data member of drag event argument for the data we're willing to receive if ( e.Data.GetDataPresent("MyNamespace.MyTreeNode2") ) { MyTreeNode2 data = null; IFormatter formatter = new BinaryFormatter(); byte[] serializedBytes = (byte[])e.Data.GetData("MyNamespace.MyTreeNode2", false); MemoryStream ms = new MemoryStream( serializedBytes ); data = (MyTreeNode2)formatter.Deserialize( ms ); ...

        H 1 Reply Last reply
        0
        • M misterbear

          Isn't it possible to serialize the raw object data from memory into a binary data format and just transport that? If I just define the MyTreeNode2 class as serializable with the [Serializable] attribute before the class definition and then I should be able to Serialize it into a byte array or something right? And that should be no problem to marshal I reckon... From what I could conclude there is built-in support for this type of binary serialization and deserialization, (BinaryFormatter class) which should mean that I should be able to use this method without a problem to transport an object.. So, if my thinking is right, can you tell me what's wrong with this? All I know is it doesn't do what I want it to... (code handling start drag event) // Create a formatter object IFormatter formatter = new BinaryFormatter(); // Create a memoryStream MemoryStream ms = new MemoryStream(); // Serialize the object (here of type MyNameSpace.MyTreeNode2) into the memory stream using the binary formatter formatter.Serialize(ms, draggedItem); // Put the byte array from the memory stream into a data object and specify the format // type to be of type "MyNameSpace.MyTreeNode2" DataObject dObj = new DataObject( "MyNamespace.MyTreeNode2", ms.GetBuffer() ); selectedTreeView.DoDragDrop( dObj, DragDropEffects.All ); and here is what I want to use on the receiving side. But it doesn't work, the method actually returns after the last line (data = ...) without even continuing execution of the remaining part of the method, or at least the debug stepper of VS won't continue past this point. (Why does this happen?) (code for handling drop event) // check the data member of drag event argument for the data we're willing to receive if ( e.Data.GetDataPresent("MyNamespace.MyTreeNode2") ) { MyTreeNode2 data = null; IFormatter formatter = new BinaryFormatter(); byte[] serializedBytes = (byte[])e.Data.GetData("MyNamespace.MyTreeNode2", false); MemoryStream ms = new MemoryStream( serializedBytes ); data = (MyTreeNode2)formatter.Deserialize( ms ); ...

          H Offline
          H Offline
          Heath Stewart
          wrote on last edited by
          #4

          An exception might be thrown that would cause execution to stop. What I described is a way of "serializing" it. You're persisting the object in global memory. Here you might have a problem depending on how .NET's DataObject handles a buffer. You still can't simply cross application boundaries with reference data (of which an array is). It needs to be either packed into memory (like strings and primitives) or locked in global memory (with COM, there's other ways where you can persist data to storage or stream it, but .NET doesn't expose that which is why I've been working on a library that - among other things - contains such an implementation). Also keep in mind that simply serializing your TreeNode derivative might not be appropriate. Remember that there are other public properties that the BinaryFormatter will traverse and serialize, like the Parent property (so you're actually serializing almost an entire tree because of the references). You should implement ISerializable and serialize only what you need (Text, Tag, etc.). Don't forget about the constructor with the serialization signature.

          Microsoft MVP, Visual C# My Articles

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups