Indeterminate with nest nodes

2 posts, 0 answers
  1. Andrew
    Andrew avatar
    1 posts
    Member since:
    Jul 2016

    Posted 15 Nov 2016 Link to this post

    I'm having an issue with regards to having multiple node levels in the treeview.

    First I load all the data into the treeview by binding a datatable as the the source.

    When you drill down in a category you'll notice that the first two nodes are not flagged as Indeterminate, but when you click on the second node to open up its children the parent nodes get refreshed and get flagged as indeterminate.

    'Loads tree nodes

          Public Sub LoadItemCategories()
            mItemCategoryDT = Datalayer.ItemCategoryRetrieveByRetail(ComboItemDataAsInt(cboRetail))

            InitTree()

            tvItemCat2.BeginUpdate()
            tvItemCat2.DisplayMember = "ItemCat"
            tvItemCat2.ParentMember = "PARENT_ITEM_CATEGORY_CD"
            tvItemCat2.ChildMember = "ITEM_CATEGORY_CD"
            tvItemCat2.DataSource = mItemCategoryDT
            tvItemCat2.EndUpdate()

            ' tvItemCat2.ExpandAll()
            AddHandler Me.tvItemCat2.NodeCheckedChanged, AddressOf tvItemCat2_NodeCheckedChanged
            AddHandler Me.tvItemCat2.NodeFormatting, AddressOf tvItemCat2_NodeFormatting

        End Sub 

     

        Private Sub tvItemCat2_NodeFormatting(sender As Object, e As TreeNodeFormattingEventArgs)
            Dim data As DataRowView = TryCast(e.Node.DataBoundItem, DataRowView)

            If data IsNot Nothing Then

                Dim value As Object = data.Row("Checked")
                If value Is DBNull.Value Then
                    e.Node.CheckState = ToggleState.Indeterminate
                Else
                    e.Node.Checked = CBool(value)
                End If
            End If


        End Sub

     

  2. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3215 posts

    Posted 17 Nov 2016 Link to this post

    Hello Andrew,

    Thank you for writing.  

    The NodeFormatting event will be fired only for the visible nodes in RadTreeView. That is why the Indeterminate state will not be applied until you display the checked inner level's node. I would like to note that currently, we do not support binding to the ToggleState.Indeterminate state automatically because it would require a change in the behavior of the Checked property. If you use the CheckedMember, the ToggleState.Indeterminate state is represented like ToggleState.On. Here is the feedback item for your reference: https://feedback.telerik.com/Project/154/Feedback/Details/155983-add-radtreeview-binding-the-check-boxes-to-support-tristatemode

    However, you can use the default mechanism for the tri-state mode in RadTreeView. Thus, you can synchronize initially the RadTreeNodes considering the values for the DataBoundItem. Then, handle the NodeCheckedChanged event and update the associated data item as well. Here is a sample code snippet which result is illustrated in the attached gif file: 
    Sub New()
     
        InitializeComponent()
          
        Me.RadTreeView1.DisplayMember = "name"
        Me.RadTreeView1.ParentMember = "pid"
        Me.RadTreeView1.ChildMember = "id"
        Me.RadTreeView1.DataSource = Me.GetSampleData()
     
        Me.RadTreeView1.CheckBoxes = True
        Me.RadTreeView1.TriStateMode = True
     
        UpdateCheckState(Me.RadTreeView1.Nodes)
     
        AddHandler Me.RadTreeView1.NodeCheckedChanged, AddressOf NodeCheckedChanged
    End Sub
     
    Private Function GetSampleData() As DataTable
        Dim dt As New DataTable()
        dt.Columns.Add("id", GetType(Integer))
        dt.Columns.Add("name", GetType(String))
        dt.Columns.Add("pid", GetType(Integer))
        dt.Columns.Add("isChecked", GetType(ToggleState))
     
        dt.Rows.Add(0, "My Computer", DBNull.Value, ToggleState.Indeterminate)
        dt.Rows.Add(1, "C:\", 0, ToggleState.Indeterminate)
        dt.Rows.Add(2, "D:\", 0, ToggleState.Off)
        dt.Rows.Add(3, "Program Files", 1, ToggleState.Indeterminate)
        dt.Rows.Add(4, "Microsoft", 3, ToggleState.Off)
        dt.Rows.Add(5, "Telerik", 3, ToggleState.On)
        dt.Rows.Add(6, "WINDOWS", 1, ToggleState.Off)
     
        Return dt
    End Function
     
    Private Sub UpdateCheckState(nodes As RadTreeNodeCollection)
        For Each node As RadTreeNode In nodes
            Dim child As DataRowView = TryCast(node.DataBoundItem, DataRowView)
            node.CheckState = child.Row(3)
            UpdateCheckState(node.Nodes)
        Next
    End Sub
     
    Private Sub NodeCheckedChanged(sender As Object, e As TreeNodeCheckedEventArgs)
        Dim child As DataRowView = TryCast(e.Node.DataBoundItem, DataRowView)
        If child IsNot Nothing Then
            child.Row(3) = e.Node.CheckState
            Console.WriteLine(e.Node.Text & " " & child.Row(3))
        End If
     
    End Sub

    Note that this is just a sample approach and it may not cover all possible cases. Feel free to modify it in a way which suits your requirement best.

    I hope this information helps. Should you have further questions I would be glad to help.

    Regards,
    Dess
    Telerik by Progress
    Telerik UI for WinForms is ready for Visual Studio 2017 RC! Learn more.
Back to Top