Reputation: 2391
I have a c# project using version 4.0 of the .net framework, and running on VS 2010. I have created a tree view populated with some extended tree nodes. I want the user to be able to copy, cut, and paste these nodes to the clipboard via a context menu or keyboard shortcuts (and not just drag-drop).
The code runs fine when copying, but when I try to paste these nodes it throws this error: Unable to cast object of type 'System.IO.MemoryStream' to type 'Namespace Path.TreeNodeEx'.
Here's my cut/copy/paste methods.
public void Copy()
{
Clipboard.SetData("Tree Node Ex", CurrentTreeNode.Clone());
}
public void Paste()
{
CurrentTreeNode.Nodes.Add((TreeNodeEx)Clipboard.GetData("Tree Node Ex"));
}
I suspect the problem is something to do with serialization, but I've tried implement the ISeralizable Interface and the [Serializable] attribute to no avail.
Any suggestions?
Upvotes: 1
Views: 2527
Reputation: 155
Old stuff but I spent a couple of hours facing the same problem so here is what works:
Imports System.Runtime.Serialization
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.TV.Nodes.Clear()
Dim tNode As New TemplateNode()
Me.TV.Nodes.Add(tNode)
For i As Integer = 1 To 5
Dim newNode As New TemplateNode()
tNode.Nodes.Add(newNode)
tNode = newNode
Next
Me.TV.ExpandAll()
End Sub
Private Sub TV_ItemDrag(sender As Object, e As ItemDragEventArgs) Handles TV.ItemDrag
DoDragDrop(Me.TV.SelectedNode, DragDropEffects.Copy + DragDropEffects.Move + DragDropEffects.Scroll)
End Sub
Private Sub TV_DragEnter(sender As Object, e As DragEventArgs) Handles TV.DragEnter
e.Effect = DragDropEffects.Move
End Sub
Private Sub TV_DragOver(sender As Object, e As DragEventArgs) Handles TV.DragOver
e.Effect = DragDropEffects.Move
If (e.KeyState And 8) = 8 Then
e.Effect += DragDropEffects.Copy
End If
End Sub
Private Sub TV_DragDrop(sender As Object, e As DragEventArgs) Handles TV.DragDrop
Dim TemplateNode As TemplateNode = e.Data.GetData(GetType(TemplateNode))
Me.TV.Nodes.Add(TemplateNode.Clone())
End Sub
Private Sub bCopy_Click(sender As Object, e As EventArgs) Handles bCopy.Click
My.Computer.Clipboard.SetData("TemplateNode", Me.TV.SelectedNode)
End Sub
Private Sub bCut_Click(sender As Object, e As EventArgs) Handles bCut.Click
My.Computer.Clipboard.SetData("TemplateNode", Me.TV.SelectedNode)
Me.TV.SelectedNode.Remove()
End Sub
Private Sub bPaste_Click(sender As Object, e As EventArgs) Handles bPaste.Click
Dim TemplateNode As TemplateNode = My.Computer.Clipboard.GetData("TemplateNode")
If Me.TV.SelectedNode Is Nothing Then
Me.TV.Nodes.Add(TemplateNode)
Else
Me.TV.SelectedNode.Nodes.Add(TemplateNode)
End If
End Sub
End Class
<Serializable()> _
Public Class TemplateNode
Inherits TreeNode
Public MyString As String = "MyStringValue"
Public MyDateTime As DateTime = DateTime.Now
Public MyBytes() As Byte
Public Sub New()
Dim buff(255) As Byte
For i As Integer = 0 To buff.GetUpperBound(0)
buff(i) = CByte(Rnd() * 100)
Next
Me.MyBytes = buff
Me.Text = Guid.NewGuid().ToString()
End Sub
Protected Friend Sub New(info As SerializationInfo, context As StreamingContext)
MyBase.New(info, context)
End Sub
End Class
Upvotes: 0
Reputation: 1
public void copy()
{
tempNode = TreeView.SelectedNode;
}
public void paste()
{
TreeView.SelectedNode.Nodes.Add(new TreeNode(tempNode.Text));
tNode = TreeView.SelectedNode.LastNode;
for (int i = 0; i <= tempNode.Nodes.Count - 1; i++)
{
TreeNode NodeClone = (TreeNode)tempNode.Nodes[i].Clone();
tNode.Nodes.Add(NodeClone);
}
public void cut()
{
tempNode = TreeView.SelectedNode;
TreeView.SelectedNode.Remove();
}
Upvotes: 0
Reputation: 2391
It turns out that attached to each extended tree node I had a dictionary that stored extra information. Apparently you can't serialize dictionaries, so this was preventing any of the tree nodes from being serialized.
I implemented ISerializable
for these extended tree nodes, and then converted the dictionary into two lists, which I then converted back to a dictionary in the deserialize constructor.
Upvotes: 1