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

Indeterminate with nest nodes

1 Answer 69 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
Andrew
Top achievements
Rank 2
Andrew asked on 15 Nov 2016, 07:31 PM

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

 

1 Answer, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 17 Nov 2016, 09:15 AM
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. 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.
Tags
Treeview
Asked by
Andrew
Top achievements
Rank 2
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or