深度复制CUSTOM树节点

时间:2019-08-06 14:25:25

标签: vb.net visual-studio

我现在正在研究几天如何浅复制和深复制从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。 拜托同事们,我真的很需要这个……我几乎因此无法入睡。任何提示将不胜感激。我是所有这些事情的新手,如果我自己说不清楚的话,对不起,英语不是我的母语。如果您需要其他说明,请随时提出,我在这里向您学习。

1 个答案:

答案 0 :(得分:0)

请勿从HDAS_TreeNode继承TreeNode。使用标准TreeNode,但将TreeNode.Tag的实例存储在其HDAS_TreeNode属性中。因此,当您在TreeView之间复制节点时,您将得到不同的TreeNode实例,它们通过其HDAS_TreeNode属性指向同一Tag实例。

换句话说,使用继承而不是继承。

相关问题