我现在正在研究几天如何浅复制和深复制从Treeview1拖放到Treeview2的自定义TreeNode对象。在我的应用程序中,我需要两种行为。我可以创建自定义TreeNode并从SQL数据库填充自定义属性。 主要思想是在Treeview1中具有所有产品选项,并在Treeview2中构建我的产品。
我能做什么...
1)从SQL数据库填充Treeview1
2)使用我的属性创建CUSTOM TreeNode
3)DragItem,DragEnter,DragOver和DragDrop我的自定义TreeNode
我怎么了?
当我从TreeView1中拖放CUSTOM TreeNode并在TreeView2中添加TreeNode时,我需要从TreeView1中删除TreeNode,但是我想在CutView1和TreeView2上都具有CUSTOM TreeNode。
我做了很多研究,但是我相信我需要您的同事一些指导才能完成我的目标。我尝试了很多事情也没有成功...这是我应该从我的CUSTOM TreeNode执行DeepCopy的代码。 DeepCopy功能的概念是我从Microsoft文档中获取的有关CLONE(浅和DeepCopy)的信息。 这是我的代码。
Imports System.ComponentModel
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Public Class Frm_USER_HDAS
Private Sub Frm_USER_HDAS_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TreeView1.Nodes.Clear()
TreeView1.Nodes.Add("Nodes_Collection")
TreeView1.Nodes(0).Text = "Nodes_Collection"
Try
Call DBOpenConnection()
Dim CurrentTableName As String = "Customers"
Dim NewNode As HDAS_TreeNode
Dim DTProperties As New DataTable
Dim returnProperties As String = DB.SQLQuery("SELECT * FROM [" + CurrentTableName + "]", DTProperties)
For j As Integer = 0 To DTProperties.Rows.Count - 1
For k As Integer = 0 To DTProperties.Columns.Count - 1
If DTProperties.Columns(k).ColumnName = "Name" Then
Dim DT_ItemProperties As New DataTable
Dim retorn_DT_ItemProperties As String = DB.SQLQuery("SELECT *
FROM [" + CurrentTableName + "]
WHERE Name = '" + DTProperties.Rows(j).Item(k) + "';",
DT_ItemProperties)
Dim DTLinks As New DataTable
Dim ReturnLinks As String = DB.SQLQuery("SELECT
c.CONSTRAINT_NAME,
cu.TABLE_NAME AS ReferencingTable,
cu.COLUMN_NAME AS ReferencingColumn,
ku.TABLE_NAME AS ReferencedTable,
ku.COLUMN_NAME AS ReferencedColumn
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS c
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu
ON cu.CONSTRAINT_NAME = c.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku
ON ku.CONSTRAINT_NAME = c.UNIQUE_CONSTRAINT_NAME
WHERE ku.TABLE_NAME = '" + CurrentTableName + "'", DTLinks)
NewNode = New HDAS_TreeNode(DTLinks, DT_ItemProperties)
TreeView1.Nodes(0).Nodes.Add(NewNode)
Exit For
End If
Next
Next
TreeView1.ExpandAll()
DB.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
#Region "Drag and Drop Process"
#Region "Started Step 1"
Private Sub TreeView1_ItemDrag(sender As Object, e As ItemDragEventArgs) Handles TreeView1.ItemDrag, TreeView2.ItemDrag
sender.DoDragDrop(e.Item, DragDropEffects.Copy)
End Sub
#End Region
#Region "Started Step 2"
Private Sub TreeView1_DragEnter(sender As Object, e As DragEventArgs) Handles TreeView1.DragEnter, TreeView2.DragEnter
e.Effect = e.AllowedEffect
End Sub
#End Region
#Region "Started Step 3"
Private Sub TreeView_DragOver(sender As Object, e As DragEventArgs) Handles TreeView1.DragOver, TreeView2.DragOver
' Retrieve the client coordinates of the mouse position.
Dim targetPoint As Point = sender.PointToClient(New Point(e.X, e.Y))
' Select the node at the mouse position.
sender.SelectedNode = sender.GetNodeAt(targetPoint)
End Sub
#End Region
#Region "Started Step 4"
Private Sub TreeView_DragDrop(sender As Object, e As DragEventArgs) Handles TreeView1.DragDrop, TreeView2.DragDrop
Dim selectedTreeview As TreeView
selectedTreeview = CType(sender, TreeView)
' Retrieve the client coordinates of the drop location.
Dim targetPoint As Point = sender.PointToClient(New Point(e.X, e.Y))
' Retrieve the node at the drop location.
Dim targetNode As HDAS_TreeNode = sender.GetNodeAt(targetPoint)
' Retrieve the node that was dragged.
Dim draggedNode As HDAS_TreeNode = CType(e.Data.GetData(GetType(HDAS_TreeNode)), HDAS_TreeNode)
Dim DroppedNode As HDAS_TreeNode = draggedNode
If Not draggedNode.Equals(targetNode) AndAlso Not ContainsNode(draggedNode, targetNode) Then
If targetNode Is Nothing Then
draggedNode.Remove() 'The Problem is here....If I remove this line I can not Keep Both Nodes
selectedTreeview.Nodes.Add(DroppedNode.DeepCopy())
Else
draggedNode.Remove() 'The Problem is here....If I remove this line I can not Keep Both Nodes
targetNode.Nodes.Add(DroppedNode.DeepCopy())
End If
draggedNode.EnsureVisible()
selectedTreeview.SelectedNode = draggedNode
sender.ExpandAll()
End If
End Sub
Private Function ContainsNode(ByVal node1 As HDAS_TreeNode, ByVal node2 As HDAS_TreeNode) As Boolean
Try
' Check the parent node of the second node.
If node2.Parent Is Nothing Then
Return False
End If
If node2.Parent.Equals(node1) Then
Return True
End If
' If the parent node is not null or equal to the first node,
' call the ContainsNode method recursively using the parent of
' the second node.
Return ContainsNode(node1, node2.Parent)
Catch ex As Exception
End Try
End Function 'ContainsNode
#End region
#Region"Here is my CUSTOM TreeNode Class"
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
<Serializable> Public Class HDAS_TreeNode
Inherits TreeNode
Private NodeName As String
Private NodeText As String
Private CurrentTableName As String
Private CurrentTablePrimaryKeys As List(Of String)
Private LinkedTableNames As List(Of String)
Private LinkedTableForeignerKeys As List(Of String)
Private PropertiesFromDB As DataTable
Private M_DTLinks As New DataTable
Private M_DTProperties As New DataTable
#Region "Constructor"
Public Sub New()
End Sub
Sub New(DTLinks As DataTable, DTProperties As DataTable)
M_DTLinks = DTLinks
M_DTProperties = DTProperties
Me.Name = HDAS_NodeName
Me.Text = HDAS_NodeText
Me.CurrentTableName = HDAS_CurrentTable
Me.CurrentTablePrimaryKeys = HDAS_PrimaryKeys
Me.LinkedTableNames = HDAS_LinkedTables
Me.LinkedTableForeignerKeys = HDAS_ForeignerKeys
Me.PropertiesFromDB = HDAS_PropertiesFromDB
End Sub
#End Region
#Region "Properties"
Public Property HDAS_NodeName As String
Get
Return MyNodeName(M_DTProperties)
End Get
Set(value As String)
NodeName = value
End Set
End Property
Public Property HDAS_NodeText As String
Get
Return MyNodeText(M_DTProperties)
End Get
Set(value As String)
NodeText = value
End Set
End Property
Public Property HDAS_CurrentTable As String
Get
Return MyNodeCurrentTable(M_DTLinks)
End Get
Set(value As String)
CurrentTableName = value
End Set
End Property
Public Property HDAS_PrimaryKeys As List(Of String)
Get
Return MyNodePrimaryKeys(M_DTLinks)
End Get
Set(value As List(Of String))
CurrentTablePrimaryKeys = value
End Set
End Property
Public Property HDAS_LinkedTables As List(Of String)
Get
Return MyNodeLinkedTableName(M_DTLinks)
End Get
Set(value As List(Of String))
LinkedTableNames = value
End Set
End Property
Public Property HDAS_ForeignerKeys As List(Of String)
Get
Return MyNodeForeignerKeys(M_DTLinks)
End Get
Set(value As List(Of String))
LinkedTableForeignerKeys = value
End Set
End Property
Public Property HDAS_PropertiesFromDB As DataTable
Get
Return M_DTProperties
End Get
Set(value As DataTable)
PropertiesFromDB = value
End Set
End Property
#End Region
#Region "Methods"
Private Function MyNodeName(DTProperties As DataTable) As String
Try
For i As Integer = 0 To DTProperties.Columns.Count
If DTProperties.Columns(i).ColumnName = "Name" Then
MyNodeName = DTProperties.Rows(0).Item(i)
Return MyNodeName
End If
Next
Catch ex As Exception
MsgBox("Class Name: HDAS_TreeNode" + vbNewLine + "Method_Name: MyNodeName" + vbNewLine + "Error_Name: " + ex.Message)
End Try
End Function
Private Function MyNodeText(DTProperties As DataTable) As String
Try
For i As Integer = 0 To DTProperties.Columns.Count
If DTProperties.Columns(i).ColumnName = "Name" Then
MyNodeText = DTProperties.Rows(0).Item(i)
Return MyNodeText
End If
Next
Catch ex As Exception
MsgBox("Class Name: HDAS_TreeNode" + vbNewLine + "Method_Name: MyNodeText" + vbNewLine + "Error_Name: " + ex.Message)
End Try
End Function
Private Function MyNodeCurrentTable(M_DTLinks As DataTable) As String
Try
MyNodeCurrentTable = M_DTLinks.Rows(0).Item(3)
Return MyNodeCurrentTable
Catch ex As Exception
MsgBox("Class Name: HDAS_TreeNode" + vbNewLine + "Method_Name: MyNodeCurrentTable" + vbNewLine + "Error_Name: " + ex.Message)
End Try
End Function
Private Function MyNodePrimaryKeys(M_DTLinks As DataTable) As List(Of String)
Try
Dim LinkedTableList As List(Of String) = Nothing
MyNodePrimaryKeys = Nothing
If M_DTLinks.Rows.Count > 1 Then
LinkedTableList = New List(Of String)
For i As Integer = 0 To M_DTLinks.Rows.Count - 1
Dim LinkedTableName As String = M_DTLinks.Rows(i).Item(4)
LinkedTableList.Add(LinkedTableName)
Next
MyNodePrimaryKeys = LinkedTableList
Return MyNodePrimaryKeys
Else
MyNodePrimaryKeys = M_DTLinks.Rows(0).Item(4)
Return MyNodePrimaryKeys
End If
Catch ex As Exception
MsgBox("Class Name: HDAS_TreeNode" + vbNewLine + "Method_Name: MyNodePrimaryKeys" + vbNewLine + "Error_Name: " + ex.Message)
End Try
End Function
Private Function MyNodeLinkedTableName(M_DTLinks As DataTable) As List(Of String)
Try
Dim LinkedTableList As List(Of String) = Nothing
MyNodeLinkedTableName = Nothing
If M_DTLinks.Rows.Count > 1 Then
LinkedTableList = New List(Of String)
For i As Integer = 0 To M_DTLinks.Rows.Count - 1
Dim LinkedTableName As String = M_DTLinks.Rows(i).Item(1)
LinkedTableList.Add(LinkedTableName)
Next
MyNodeLinkedTableName = LinkedTableList
Return MyNodeLinkedTableName
Else
MyNodeLinkedTableName = M_DTLinks.Rows(0).Item(1)
Return MyNodeLinkedTableName
End If
Catch ex As Exception
MsgBox("Class Name: HDAS_TreeNode" + vbNewLine + "Method_Name: MyNodeLinkedTableName" + vbNewLine + "Error_Name: " + ex.Message)
End Try
End Function
Private Function MyNodeForeignerKeys(M_DTLinks As DataTable) As List(Of String)
Try
Dim LinkedTableList As List(Of String) = Nothing
MyNodeForeignerKeys = Nothing
If M_DTLinks.Rows.Count > 1 Then
LinkedTableList = New List(Of String)
For i As Integer = 0 To M_DTLinks.Rows.Count - 1
Dim LinkedTableName As String = M_DTLinks.Rows(i).Item(2)
LinkedTableList.Add(LinkedTableName)
Next
MyNodeForeignerKeys = LinkedTableList
Return MyNodeForeignerKeys
Else
MyNodeForeignerKeys = M_DTLinks.Rows(0).Item(2)
Return MyNodeForeignerKeys
End If
Catch ex As Exception
MsgBox("Class Name: HDAS_TreeNode" + vbNewLine + "Method_Name: MyNodeForeignerKeys" + vbNewLine + "Error_Name: " + ex.Message)
End Try
End Function
Public Function DeepCopy() As HDAS_TreeNode
Dim theClone As HDAS_TreeNode = DirectCast(Me.MemberwiseClone(), HDAS_TreeNode)
theClone.HDAS_NodeName = String.Copy(HDAS_NodeName)
theClone.HDAS_NodeText = String.Copy(HDAS_NodeText)
theClone.HDAS_CurrentTable = String.Copy(HDAS_CurrentTable)
theClone.HDAS_PrimaryKeys = New List(Of String)(HDAS_PrimaryKeys)
theClone.HDAS_LinkedTables = New List(Of String)(HDAS_LinkedTables)
theClone.HDAS_ForeignerKeys = New List(Of String)(HDAS_ForeignerKeys)
theClone.HDAS_PropertiesFromDB = PropertiesFromDB.Copy
Return theClone
End Function
#End Region
End Class
我期望在拖放过程和方法之后在两个TreeView中都具有Custom TreeNode,以使用我的CUSTOM TreeNode中的Shallow和DeepCopy。 拜托同事们,我真的很需要这个……我几乎因此无法入睡。任何提示将不胜感激。我是所有这些事情的新手,如果我自己说不清楚的话,对不起,英语不是我的母语。如果您需要其他说明,请随时提出,我在这里向您学习。
答案 0 :(得分:0)
请勿从HDAS_TreeNode
继承TreeNode
。使用标准TreeNode
,但将TreeNode.Tag
的实例存储在其HDAS_TreeNode
属性中。因此,当您在TreeView
之间复制节点时,您将得到不同的TreeNode
实例,它们通过其HDAS_TreeNode
属性指向同一Tag
实例。
换句话说,使用继承而不是继承。