This is a migrated thread and some comments may be shown as answers.

Drag & Drop with Nodes Templates

1 Answer 102 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
laplace82
Top achievements
Rank 1
laplace82 asked on 07 Jan 2009, 08:37 AM
I defined a RadTreeView using a template for nodes.
Every node must contain a dropDownList and a Label, filled from a DataTable.

I have 2 problems:
1) When i try Drag & Drop nodes i get an error derived from the DropDownList;
2) if i don't put the DropDownList in the Template (so only the Label) after the drag & drop i lost the template and data fails.

How can i solve this 2 problems?
Above the code.
Thanks a lot.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>  
  
<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>  
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head runat="server">  
    <title></title>  
</head>  
<body>  
    <form id="form1" runat="server">  
      
    <asp:ScriptManager ID="ScriptManager1" runat="server">  
    </asp:ScriptManager>     
    <div>  
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">  
            <ContentTemplate>  
                <telerik:RadTreeView ID="RadTreeView1" Runat="server" EnableDragAndDrop="True" EnableDragAndDropBetweenNodes="True" Skin="Outlook" >  
                </telerik:RadTreeView>  
            </ContentTemplate>  
        </asp:UpdatePanel>  
      
    </div>  
    </form>  
</body>  
</html>  
  

Option Strict On  
  
Imports System.Data  
Imports System.Web.UI  
Imports Telerik.Web.UI  
  
  
  
Partial Class _Default : Inherits System.Web.UI.Page  
  
    Dim myDataSet As DataSet  
  
    Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load  
        If Not Page.IsPostBack Then  
  
            myDataSet = New DataSet  
            Dim tb As DataTable = New DataTable("Prova")  
            tb.Columns.Add(New DataColumn("id"))  
            tb.Columns.Add(New DataColumn("name"))  
            tb.Columns.Add(New DataColumn("code"))  
            tb.Columns.Add(New DataColumn("parent"))  
            tb.Columns.Add(New DataColumn("sign"))  
  
            myDataSet.Tables.Add(tb)  
            Dim row As DataRow = myDataSet.Tables("Prova").NewRow()  
            row("id") = 1  
            row("name") = "total"  
            row("code") = 0  
            row("parent") = DBNull.Value  
            row("sign") = DBNull.Value  
            myDataSet.Tables("Prova").Rows.Add(row)  
  
            row = myDataSet.Tables("Prova").NewRow()  
            row("id") = 2  
            row("name") = "liv1"  
            row("code") = 1  
            row("parent") = 0  
            row("sign") = "+"  
            myDataSet.Tables("prova").Rows.Add(row)  
  
            row = myDataSet.Tables("Prova").NewRow()  
            row("id") = 3  
            row("name") = "liv2"  
            row("code") = 2  
            row("parent") = 0  
            row("sign") = "-"  
            myDataSet.Tables("prova").Rows.Add(row)  
  
            row = myDataSet.Tables("Prova").NewRow()  
            row("id") = 4  
            row("name") = "sub-liv1"  
            row("code") = 3  
            row("parent") = 1  
            row("sign") = "tilde"  
            myDataSet.Tables("prova").Rows.Add(row)  
  
            Dim keyColumn(1) As DataColumn  
            keyColumn(0) = myDataSet.Tables("Prova").Columns.Item("id")  
            myDataSet.Tables("Prova").PrimaryKey = keyColumn  
  
            RadTreeView1.NodeTemplate = New myNodeTemplate(myDataSet)  
  
            RadTreeView1.DataSource = myDataSet.Tables("Prova")  
            RadTreeView1.DataTextField = "name"  
            RadTreeView1.DataFieldID = "code"  
            RadTreeView1.DataFieldParentID = "parent"  
            RadTreeView1.DataValueField = "id"  
            RadTreeView1.DataBind()  
            RadTreeView1.ExpandAllNodes()  
  
            Session("RicordaDataSet") = myDataSet  
        Else  
            myDataSet = CType(Session("RicordaDataSet"), DataSet)  
        End If  
  
    End Sub  
  
    Protected Sub RadTreeView1_HandleDrop(ByVal sender As ObjectByVal e As RadTreeNodeDragDropEventArgs) Handles RadTreeView1.NodeDrop  
        Dim sourceNode As RadTreeNode = e.SourceDragNode  
        Dim destNode As RadTreeNode = e.DestDragNode  
        Dim dropPosition As RadTreeViewDropPosition = e.DropPosition  
  
        If destNode IsNot Nothing Then  
            If (sourceNode.TreeView.SelectedNodes.Count <= 1) Then  
                PerformDragAndDrop(dropPosition, sourceNode, destNode)  
            ElseIf (sourceNode.TreeView.SelectedNodes.Count > 1) Then  
                For Each node As RadTreeNode In sourceNode.TreeView.SelectedNodes  
                    PerformDragAndDrop(dropPosition, node, destNode)  
                Next  
            End If  
  
            destNode.Expanded = True  
            sourceNode.TreeView.ClearSelectedNodes()  
        End If  
    End Sub  
  
  
    Private Sub PerformDragAndDrop(ByVal dropPosition As RadTreeViewDropPosition, ByVal sourceNode As RadTreeNode, ByVal destNode As RadTreeNode)  
        If (sourceNode.Equals(destNode) OrElse sourceNode.IsAncestorOf(destNode)) Then  
            Return  
        End If  
        sourceNode.Owner.Nodes.Remove(sourceNode)  
        Select Case (dropPosition)  
            Case RadTreeViewDropPosition.Over ' child  
                If Not sourceNode.IsAncestorOf(destNode) Then  
                    modifyDataSetAfterDragAndDrop(sourceNode, destNode, 1)  
                    destNode.Nodes.Add(sourceNode)  
                End If  
            Case RadTreeViewDropPosition.Above ' sibling - above              
                modifyDataSetAfterDragAndDrop(sourceNode, destNode, 0)  
                destNode.InsertBefore(sourceNode)  
            Case RadTreeViewDropPosition.Below ' sibling - below  
                modifyDataSetAfterDragAndDrop(sourceNode, destNode, 0)  
                destNode.InsertAfter(sourceNode)  
        End Select  
    End Sub  
  
  
    Protected Sub modifyDataSetAfterDragAndDrop(ByVal sourceNode As RadTreeNode, ByVal destNode As RadTreeNode, ByVal flag As Integer)  
        Dim sourceRow As DataRow = myDataSet.Tables("Prova").Rows.Find(sourceNode.Value)  
        Dim destRow As DataRow = myDataSet.Tables("Prova").Rows.Find(destNode.Value)  
        If flag = 1 Then ' Nodo spostato a sotto-nodo di un altro  
            sourceRow("parent") = destRow("code")  
        Else ' Nodo inserito tra altri 2 nodi  
            sourceRow("parent") = destRow("parent")  
        End If  
    End Sub  
  
  
    Class myNodeTemplate : Implements ITemplate  
  
        Dim myDataSetHere As DataSet  
  
        Sub New(ByVal type As DataSet)  
            myDataSetHere = type  
        End Sub  
  
  
        Public Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn  
            Dim ddl1 As New DropDownList()  
            ddl1.Items.Add(New ListItem("Nothing", DBNull.Value.ToString))  
            ddl1.Items.Add(New ListItem("+""+"))  
            ddl1.Items.Add(New ListItem("-""-"))  
            ddl1.Items.Add(New ListItem("tilde""tilde"))  
            ddl1.ID = "ItemDropDownList"  
            ddl1.Text = "Text"  
  
            Dim label1 As New Label()  
            label1.ID = "ItemLabel"  
            label1.Text = "Text"  
            label1.Font.Size = 10  
            label1.Font.Bold = True  
  
            AddHandler label1.DataBinding, AddressOf label1_DataBinding  
            AddHandler ddl1.DataBinding, AddressOf ddl1_DataBinding  
            container.Controls.Add(ddl1)  
            Dim ll As Label = New Label  
            ll.Text = "   "  
            container.Controls.Add(ll)  
            container.Controls.Add(label1)  
        End Sub  
  
  
        Private Sub label1_DataBinding(ByVal sender As ObjectByVal e As EventArgs)  
            Dim target As Label = DirectCast(sender, Label)  
            Dim node As RadTreeNode = DirectCast(target.BindingContainer, RadTreeNode)  
            Dim nodeText As String = DirectCast(DataBinder.Eval(node, "Text"), String)  
            target.Text = nodeText  
        End Sub  
  
  
        Private Sub ddl1_DataBinding(ByVal sender As ObjectByVal e As EventArgs)  
            Dim target As DropDownList = DirectCast(sender, DropDownList)  
            Dim node As RadTreeNode = DirectCast(target.BindingContainer, RadTreeNode)  
            Dim nodeId As String = node.Value  
  
            Dim keyColumn(1) As DataColumn  
            keyColumn(0) = myDataSetHere.Tables("Prova").Columns.Item("id")  
            myDataSetHere.Tables("Prova").PrimaryKey = keyColumn  
  
            Dim row As DataRow = myDataSetHere.Tables("Prova").Rows.Find(node.Value)  
            target.SelectedValue = row("sign").ToString  
        End Sub  
    End Class  
End Class  
  
  

1 Answer, 1 is accepted

Sort by
0
laplace82
Top achievements
Rank 1
answered on 08 Jan 2009, 01:43 PM
Since the template must be called fo every nodes i modify the code so now every drag & drop the RadTreeView is loaded form datasource and by dataBind().
The code  posted in this post works well without templates but when i add the template the treview is build wrong.

Where is the problem?

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>  
  
<%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>  
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head runat="server">  
    <title></title>  
</head>  
<body>  
    <form id="form1" runat="server">  
      
    <asp:ScriptManager ID="ScriptManager1" runat="server" AsyncPostBackTimeout="9000"></asp:ScriptManager>     
    <div>      
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">  
        <ContentTemplate>  
            <telerik:RadTreeView ID="RadTreeView1" Runat="server" EnableDragAndDrop="True"  
                EnableDragAndDropBetweenNodes="True" Skin="Outlook" >  
            </telerik:RadTreeView>  
        </ContentTemplate>  
    </asp:UpdatePanel>  
    </div>  
    </form>  
</body>  
</html>  
  

Option Strict On  
  
Imports System.Data  
Imports System.Web.UI  
Imports Telerik.Web.UI  
  
  
  
Partial Class _Default : Inherits System.Web.UI.Page  
  
    Dim myDataSet As DataSet  
  
    Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load  
        If Not Page.IsPostBack Then  
  
            myDataSet = New DataSet  
            Dim tb As DataTable = New DataTable("Prova")  
            tb.Columns.Add(New DataColumn("id"))  
            tb.Columns.Add(New DataColumn("name"))  
            tb.Columns.Add(New DataColumn("code"))  
            tb.Columns.Add(New DataColumn("parentNode"))  
            tb.Columns.Add(New DataColumn("sign"))  
            tb.Columns.Add(New DataColumn("index"))  
  
            myDataSet.Tables.Add(tb)  
            Dim row As DataRow = myDataSet.Tables("Prova").NewRow()  
            row("id") = 1  
            row("name") = "total"  
            row("code") = 0  
            row("parentNode") = DBNull.Value  
            row("sign") = DBNull.Value  
            row("index") = 0  
            myDataSet.Tables("Prova").Rows.Add(row)  
  
            row = myDataSet.Tables("Prova").NewRow()  
            row("id") = 2  
            row("name") = "liv1"  
            row("code") = 1  
            row("parentNode") = 0  
            row("sign") = "+"  
            row("index") = 1  
            myDataSet.Tables("prova").Rows.Add(row)  
  
            row = myDataSet.Tables("Prova").NewRow()  
            row("id") = 3  
            row("name") = "liv2"  
            row("code") = 2  
            row("parentNode") = 0  
            row("sign") = "-"  
            row("index") = 0  
            myDataSet.Tables("prova").Rows.Add(row)  
  
            row = myDataSet.Tables("Prova").NewRow()  
            row("id") = 4  
            row("name") = "sub-liv1"  
            row("code") = 3  
            row("parentNode") = 1  
            row("sign") = "tilde"  
            row("index") = 0  
            myDataSet.Tables("prova").Rows.Add(row)  
  
            Dim keyColumn(1) As DataColumn  
            keyColumn(0) = myDataSet.Tables("Prova").Columns.Item("id")  
            myDataSet.Tables("Prova").PrimaryKey = keyColumn  
  
            myDataSet.Tables("Prova").DefaultView.Sort = "parentNode, index ASC"  
            RadTreeView1.DataTextField = "name"  
            RadTreeView1.DataFieldID = "code"  
            RadTreeView1.DataFieldParentID = "parentNode"  
            RadTreeView1.DataValueField = "id"  
            RadTreeView1.DataSource = myDataSet.Tables("Prova").DefaultView  
            RadTreeView1.NodeTemplate = New myNodeTemplate(myDataSet)  
            RadTreeView1.DataBind()  
            RadTreeView1.ExpandAllNodes()  
            RadTreeView1.Nodes.Item(0).ToolTip = "aaa"  
  
            Session("RememberDataSet") = myDataSet  
        Else  
            myDataSet = CType(Session("RememberDataSet"), DataSet)  
        End If  
    End Sub  
  
  
    Protected Sub RadTreeView1_HandleDrop(ByVal sender As ObjectByVal e As RadTreeNodeDragDropEventArgs) Handles RadTreeView1.NodeDrop  
        Dim sourceNode As RadTreeNode = e.SourceDragNode  
        Dim destNode As RadTreeNode = e.DestDragNode  
        Dim dropPosition As RadTreeViewDropPosition = e.DropPosition  
  
        If destNode IsNot Nothing Then  
            If (sourceNode.TreeView.SelectedNodes.Count <= 1) Then  
                PerformDragAndDrop(dropPosition, sourceNode, destNode)  
            ElseIf (sourceNode.TreeView.SelectedNodes.Count > 1) Then  
                For Each node As RadTreeNode In sourceNode.TreeView.SelectedNodes  
                    PerformDragAndDrop(dropPosition, node, destNode)  
                Next  
            End If  
  
            destNode.Expanded = True  
            sourceNode.TreeView.ClearSelectedNodes()  
  
            myDataSet.Tables("Prova").DefaultView.RowFilter = ""  
            myDataSet.Tables("Prova").DefaultView.Sort = "parentNode, index ASC"  
            RadTreeView1.Nodes.Clear()  
            RadTreeView1.DataTextField = "name"  
            RadTreeView1.DataFieldID = "code"  
            RadTreeView1.DataFieldParentID = "parentNode"  
            RadTreeView1.DataValueField = "id"  
            RadTreeView1.DataSource = myDataSet.Tables("Prova").DefaultView  
            RadTreeView1.NodeTemplate = New myNodeTemplate(myDataSet)  
            RadTreeView1.DataBind()  
            RadTreeView1.ExpandAllNodes()  
        End If  
    End Sub  
  
  
    Private Sub PerformDragAndDrop(ByVal dropPosition As RadTreeViewDropPosition, ByVal sourceNode As RadTreeNode, ByVal destNode As RadTreeNode)  
        If (sourceNode.Equals(destNode) OrElse sourceNode.IsAncestorOf(destNode)) Then  
            Return  
        End If  
          
        sourceNode.Owner.Nodes.Remove(sourceNode)  
        Select Case (dropPosition)  
            Case RadTreeViewDropPosition.Over ' child  
                If Not sourceNode.IsAncestorOf(destNode) Then  
                    'destNode.Nodes.Add(sourceNode)  
                    modifyDataSetAfterDragAndDrop(sourceNode, destNode, 1)  
                End If  
            Case RadTreeViewDropPosition.Above ' sibling - above              
                'destNode.InsertBefore(sourceNode)  
                modifyDataSetAfterDragAndDrop(sourceNode, destNode, 2)  
            Case RadTreeViewDropPosition.Below ' sibling - below  
                'destNode.InsertAfter(sourceNode)  
                modifyDataSetAfterDragAndDrop(sourceNode, destNode, 3)  
        End Select  
    End Sub  
  
  
    Protected Sub modifyDataSetAfterDragAndDrop(ByVal sourceNode As RadTreeNode, ByVal destNode As RadTreeNode, ByVal flag As Integer)  
        Dim sourceRow As DataRow = myDataSet.Tables("Prova").Rows.Find(sourceNode.Value)  
        Dim destRow As DataRow = myDataSet.Tables("Prova").Rows.Find(destNode.Value)  
        Dim refIndex As Integer = Integer.Parse(destRow("index").ToString)  
  
        If destRow("parentNode").ToString = DBNull.Value.ToString Then  
            myDataSet.Tables("Prova").DefaultView.RowFilter = "parentNode Is Null"  
        Else  
            myDataSet.Tables("Prova").DefaultView.RowFilter = "parentNode = " & destRow("parentNode").ToString  
        End If  
  
        myDataSet.Tables("Prova").DefaultView.Sort = "index"  
  
        If flag = 1 Then ' child  
            sourceRow("parentNode") = destRow("code")  
            sourceRow("index") = Integer.Parse(destRow("index").ToString) + 1  
        ElseIf flag = 2 Then ' sibling - above  
            For i As Integer = 0 To myDataSet.Tables("Prova").DefaultView.Count - 1  
                If Integer.Parse(myDataSet.Tables("Prova").DefaultView.Item(i).Item("index").ToString) >= refIndex Then  
                    myDataSet.Tables("Prova").DefaultView.Item(i).Item("index") = Integer.Parse(myDataSet.Tables("Prova").DefaultView.Item(i).Item("index").ToString) + 1  
                End If  
            Next  
            sourceRow("parentNode") = destRow("parentNode")  
            sourceRow("index") = refIndex  
        ElseIf flag = 3 Then ' sibling - below  
            For i As Integer = 0 To myDataSet.Tables("Prova").DefaultView.Count - 1  
                If Integer.Parse(myDataSet.Tables("Prova").DefaultView.Item(i).Item("index").ToString) > refIndex Then  
                    myDataSet.Tables("Prova").DefaultView.Item(i).Item("index") = Integer.Parse(myDataSet.Tables("Prova").DefaultView.Item(i).Item("index").ToString) + 1  
                End If  
            Next  
            sourceRow("parentNode") = destRow("parentNode")  
            sourceRow("index") = refIndex + 1  
        End If  
    End Sub  
End Class  
  
  
  
Class myNodeTemplate : Implements ITemplate  
  
    Dim myDataTableHere As DataSet  
  
  
    Sub New(ByVal type As DataSet)  
        myDataTableHere = type  
    End Sub  
  
  
    Public Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn  
        'Dim ddl1 As New DropDownList()  
        'ddl1.Items.Add(New ListItem("Nothing", DBNull.Value.ToString))  
        'ddl1.Items.Add(New ListItem("+", "+"))  
        'ddl1.Items.Add(New ListItem("-", "-"))  
        'ddl1.Items.Add(New ListItem("tilde", "tilde"))  
        'ddl1.ID = "ItemDropDownList"  
        'ddl1.Text = "Text"  
  
        Dim label1 As New Label()  
        label1.ID = "ItemLabel"  
        label1.Text = "Text"  
        label1.Font.Size = 10  
        label1.Font.Bold = True  
  
        AddHandler label1.DataBinding, AddressOf label1_DataBinding  
        'AddHandler ddl1.DataBinding, AddressOf ddl1_DataBinding  
        'container.Controls.Add(ddl1)  
        container.Controls.Add(label1)  
    End Sub  
  
  
    Private Sub label1_DataBinding(ByVal sender As ObjectByVal e As EventArgs)  
        Dim target As Label = DirectCast(sender, Label)  
        Dim node As RadTreeNode = DirectCast(target.BindingContainer, RadTreeNode)  
        Dim nodeText As String = DirectCast(DataBinder.Eval(node, "Text"), String)  
        target.Text = nodeText  
    End Sub  
  
  
    Private Sub ddl1_DataBinding(ByVal sender As ObjectByVal e As EventArgs)  
        Dim target As DropDownList = DirectCast(sender, DropDownList)  
        Dim node As RadTreeNode = DirectCast(target.BindingContainer, RadTreeNode)  
        Dim nodeId As String = node.Value  
  
        Dim row As DataRow = myDataTableHere.Tables("Prova").Rows.Find(node.Value)  
        target.SelectedValue = row("sign").ToString  
    End Sub  
End Class  
Tags
TreeView
Asked by
laplace82
Top achievements
Rank 1
Answers by
laplace82
Top achievements
Rank 1
Share this question
or