Wizard
Wizard

Reputation: 1162

Populating a tree view

I am trying to populate a tree view with task and subtasks, those subtasks acting as the child node for that specific task.

I am getting an error that says on the line commented showing the error, am I going about this all wrong or have I missed something stupid?

"An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in System.Windows.Forms.dll"

 private void updateTreeView()
        {   

            //Clear before entry
            treeActiveTasks.Nodes.Clear(); 

            treeActiveTasks.BeginUpdate();    

            int parentCount = 0;

            //Update tasks
            foreach (Task task in m_user.Tasks)
            {
                if (!task.IsComplete)
                {
                    treeActiveTasks.Nodes[parentCount].Nodes.Add(task.Title); //Error showing on this line

                    int i = 0;
                    foreach (Subtask subtask in task.Subtasks)
                    {
                        if (!subtask.IsComplete)
                        {
                            treeActiveTasks.Nodes[0].Nodes[0].Nodes.Add(subtask.Title);
                        }                     

                        i++;
                    }
                    parentCount++;
                }               
            }


            treeActiveTasks.EndUpdate();
        }

Upvotes: 0

Views: 380

Answers (2)

Wizard
Wizard

Reputation: 1162

I worked out what the problem was, I was adding child nodes to parents that I hadn't yet created, hence the exception. Code as follows:

//Clear before entry
    treeActiveTasks.Nodes.Clear(); 

    treeActiveTasks.BeginUpdate();




    int parentCount = 0;

    //Update tasks
    foreach (Task task in m_user.Tasks)
    {
        if (!task.IsComplete)
        {
            treeActiveTasks.Nodes.Add(task.Title); 


            foreach (Subtask subtask in task.Subtasks)
            {
                if (!subtask.IsComplete)
                {
                    treeActiveTasks.Nodes[parentCount].Nodes.Add(subtask.Title);
                }

            }
            parentCount++;
        }
    }


    treeActiveTasks.EndUpdate();

Upvotes: 0

Michael Gunter
Michael Gunter

Reputation: 12811

The first time treeActiveTasks.Nodes[parentCount] is evaluated, the Nodes collection is empty (you've explicitly cleared it a few lines above), so when you pass in index 0 (the value of parentCount), you get an ArgumentOutOfRangeException.

I think you want something like this:

private void updateTreeView()
{   
    treeActiveTasks.BeginUpdate();    
    treeActiveTasks.Nodes.Clear(); 
    foreach (var task in m_user.Tasks)
    {
        if (!task.IsComplete)
        {
            var taskNode = treeActiveTasks.Nodes.Add(task.Title);
            foreach (var subtask in task.Subtasks)
                if (!subtask.IsComplete)
                    taskNode.Nodes.Add(subtask.Title);
        }               
    }
    treeActiveTasks.EndUpdate();
}

Or use LINQ:

private void updateTreeView()
{   
    treeActiveTasks.BeginUpdate();    
    treeActiveTasks.Nodes.Clear();
    treeActiveTasks.Nodes.AddRange(
        (from task in m_user.Tasks
         where !task.IsComplete
         select new TreeNode(
             task.Title,
             (from subtask in task.Subtasks
              where !subtask.IsComplete
              select new TreeNode(subtask.Title)
             ).ToArray())
        ).ToArray());
    treeActiveTasks.EndUpdate();
}

Upvotes: 1

Related Questions