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

Dynamic updating of Treeview Nodes

4 Answers 1471 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
Donovan Bell
Top achievements
Rank 1
Donovan Bell asked on 07 Mar 2011, 08:54 AM
Hi,

I'm looking for advice on achieving dynamic updating of treeview nodes...

The purpose of the RadTreeview in my project is to display computer objects (Computer name, and corresponding Icon (imagekey)).

I have a method that executes on a different thread that applies the necassary changes to the treeview, i.e. if a computer status changes (is not reachable, etc) - it updates the necassary node's imageKey with the appropriate image.

However, the changes to the node only appear if I expand or contract a parent node, or add /delete a node, etc.
What is the best way to achieve a dynamic update without user intevention or reloading the tree?

4 Answers, 1 is accepted

Sort by
0
Emanuel Varga
Top achievements
Rank 1
answered on 08 Mar 2011, 08:57 AM
Hello Donovan,

Just wrap your change statements in
radTreeView1.BeginUpdate();
// perform changes here
radTreeView1.EndUpdate();

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Donovan Bell
Top achievements
Rank 1
answered on 08 Mar 2011, 09:13 AM
Thanks, but get a "Bounds cannot be changed while locked." exception when EndUpdate() method is called.

Any Ideas?
0
Emanuel Varga
Top achievements
Rank 1
answered on 08 Mar 2011, 09:21 AM
Hello again Donovan,

I don't know exactly what you are doing there but please take a look at the following example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Telerik.WinControls.Commands;
using Telerik.WinControls.UI;
 
public partial class Form1 : Form
{
    private RadTreeView radTreeView1;
    private List<TestObject> collection;
    private BackgroundWorker backgroundWorker;
 
    public Form1()
    {
        InitializeComponent();
        collection = new List<TestObject>();
        this.Size = new Size(400, 300);
        this.Controls.Add(radTreeView1 = new RadTreeView());
        radTreeView1.Dock = DockStyle.Fill;
        radTreeView1.ParentIDMember = "ParentId";
        radTreeView1.ValueMember = "Id";
        radTreeView1.DisplayMember = "Text";
 
        collection.Add(new TestObject { Id = 1, ParentId = 0, Text = "Parent1" });
        collection.Add(new TestObject { Id = 2, ParentId = 0, Text = "Parent2" });
        collection.Add(new TestObject { Id = 3, ParentId = 0, Text = "Parent3" });
        collection.Add(new TestObject { Id = 4, ParentId = 1, Text = "Child1" });
        collection.Add(new TestObject { Id = 5, ParentId = 1, Text = "Child2" });
        collection.Add(new TestObject { Id = 6, ParentId = 1, Text = "Child3" });
        collection.Add(new TestObject { Id = 7, ParentId = 2, Text = "Child4" });
        collection.Add(new TestObject { Id = 8, ParentId = 3, Text = "Child4" });
        collection.Add(new TestObject { Id = 9, ParentId = 3, Text = "Child5" });
        radTreeView1.DataSource = collection;
 
        var button = new RadToggleButton();
        button.Dock = DockStyle.Bottom;
        button.Text = "Start / Stop updates";
        button.ToggleStateChanged += new StateChangedEventHandler(button_ToggleStateChanged);
        this.Controls.Add(button);
 
        backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
        backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.WorkerSupportsCancellation = true;
    }
 
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        radTreeView1.ExpandAll();
    }
 
    void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        var listItem = e.UserState as TestObject;
        if (listItem == null)
        {
            return;
        }
 
        UpdateTreeNode(listItem);
    }
 
    private void UpdateTreeNode(TestObject listItem)
    {
        radTreeView1.BeginUpdate();
        var text = listItem.Text;
        RadTreeNode node = null;
        FindByTextCommand cmd = new FindByTextCommand();
        List<object> result = RadTreeView.ExecuteBatchCommand(this.radTreeView1.Nodes, -1, cmd, text);
        if (result != null)
        {
            node = result.FirstOrDefault() as RadTreeNode;
        }
 
        if (text.Contains("Parent"))
        {
            var num = 0;
            var numText = text.Replace("Parent", string.Empty);
            int.TryParse(numText, out num);
            ++num;
            text = "Parent" + num.ToString();
        }
        else
        {
            var num = 0;
            var numText = text.Replace("Child", string.Empty);
            int.TryParse(numText, out num);
            ++num;
            text = "Child" + num.ToString();
        }
 
        if (node != null)
        {
            node.Text = text;
        }
 
        radTreeView1.EndUpdate();
    }
 
    void button_ToggleStateChanged(object sender, StateChangedEventArgs args)
    {
        if (backgroundWorker.IsBusy)
        {
            backgroundWorker.CancelAsync();
        }
        else
        {
            backgroundWorker.RunWorkerAsync();
        }
    }
 
    void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        while (!backgroundWorker.CancellationPending)
        {
            var num = new Random(DateTime.Now.Millisecond).Next(0, collection.Count - 1);
            backgroundWorker.ReportProgress(0, collection[num]);
            Thread.Sleep(100 + DateTime.Now.Millisecond / 100 + num);
        }
    }
}
 
public class TestObject
{
    private int id;
 
    public int Id
    {
        get { return id; }
        set { id = value; }
    }
 
    private int parentId;
 
    public int ParentId
    {
        get { return parentId; }
        set { parentId = value; }
    }
 
    private string text;
 
    public string Text
    {
        get { return text; }
        set
        {
            text = value;
        }
    }
}

This should help you achieve dynamic updates,
Second, you should keep an eye out for the new and improved tree view that is scheduled for release sometime in the middle of march.

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga
Telerik WinForms MVP
0
Donovan Bell
Top achievements
Rank 1
answered on 08 Mar 2011, 09:25 AM
Thanks! May need to change my model slightly - thanks for the help!
Tags
Treeview
Asked by
Donovan Bell
Top achievements
Rank 1
Answers by
Emanuel Varga
Top achievements
Rank 1
Donovan Bell
Top achievements
Rank 1
Share this question
or