Drag & Drop with Nodes Templates

2 posts, 0 answers
  1. laplace82
    laplace82 avatar
    6 posts
    Member since:
    Dec 2008

    Posted 07 Jan 2009 Link to this post

    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  
      
      
  2. laplace82
    laplace82 avatar
    6 posts
    Member since:
    Dec 2008

    Posted 08 Jan 2009 Link to this post

    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  
Back to Top