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

Using RadListControl to display rolling items

4 Answers 193 Views
ListControl
This is a migrated thread and some comments may be shown as answers.
Bibek
Top achievements
Rank 1
Bibek asked on 10 Feb 2011, 06:37 PM
Hi,

I want to use RadListControl to display the logs of the ongoing large process in background thread. I will be adding hundred thousands of items into the control in main thread.

But to make everything simple, before adding item to the control, I am checking if the item count is more than 100, if it is more than 100 I am removing the top most Item, then only I am adding the new item. After adding I am scrolling the listbox control down to the last item.

This process may run for more than 10 hrs and my application may not respond as it is dealing with too much of items every seconds.

I am looking for most efficeint way to do this as with listboxcontrol after running for about 1 hr application is not able to handle the number of items and not responding.

I am using following code: 

            RadListDataItem newItem = new RadListDataItem(message);
            radListControl1.Items.Add(newItem);
            if (radListControl1.Items.Count > 100)
            {
                radListControl1.Items.RemoveAt(0);              
            }           
            radListControl1.ScrollToItem(newItem);

But if I am using windows listboxcontrol I am able to do without any problem.

            listBox1.Items.Add(message);

            if (listBox1.Items.Count > 100)
            {
                listBox1.Items.RemoveAt(0);               
            }
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            listBox1.ClearSelected();   

I want to use RadListControl because it can handle html syntax.

Please suggest something on this. I can even switch to another control which supports html code.

regards,

Bibek Dawadi

4 Answers, 1 is accepted

Sort by
0
Richard Slade
Top achievements
Rank 2
answered on 10 Feb 2011, 10:53 PM
Hello,

you could try something like the following, using a background worker and updating the scroll via the progress changed event

Designer File
namespace RadListControl_LargsItems_CS
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components;
  
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
  
        #region Windows Form Designer generated code
  
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.radListControl1 = new Telerik.WinControls.UI.RadListControl();
            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
            this.radButtonTest = new Telerik.WinControls.UI.RadButton();
            this.radButtonStop = new Telerik.WinControls.UI.RadButton();
            ((System.ComponentModel.ISupportInitialize)(this.radListControl1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.radButtonTest)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.radButtonStop)).BeginInit();
            this.SuspendLayout();
            // 
            // radListControl1
            // 
            this.radListControl1.CaseSensitiveSort = true;
            this.radListControl1.Dock = System.Windows.Forms.DockStyle.Left;
            this.radListControl1.Location = new System.Drawing.Point(0, 0);
            this.radListControl1.Name = "radListControl1";
            this.radListControl1.Size = new System.Drawing.Size(236, 262);
            this.radListControl1.TabIndex = 0;
            this.radListControl1.Text = "radListControl1";
            // 
            // backgroundWorker1
            // 
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
            this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
            // 
            // radButtonTest
            // 
            this.radButtonTest.Location = new System.Drawing.Point(252, 30);
            this.radButtonTest.Name = "radButtonTest";
            this.radButtonTest.Size = new System.Drawing.Size(102, 24);
            this.radButtonTest.TabIndex = 1;
            this.radButtonTest.Text = "Show Message";
            this.radButtonTest.Click += new System.EventHandler(this.radButtonTest_Click);
            // 
            // radButtonStop
            // 
            this.radButtonStop.Location = new System.Drawing.Point(252, 226);
            this.radButtonStop.Name = "radButtonStop";
            this.radButtonStop.Size = new System.Drawing.Size(102, 24);
            this.radButtonStop.TabIndex = 2;
            this.radButtonStop.Text = "Stop";
            this.radButtonStop.Click += new System.EventHandler(this.radButtonStop_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(366, 262);
            this.Controls.Add(this.radButtonStop);
            this.Controls.Add(this.radButtonTest);
            this.Controls.Add(this.radListControl1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.radListControl1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.radButtonTest)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.radButtonStop)).EndInit();
            this.ResumeLayout(false);
  
        }
  
        #endregion
  
        private Telerik.WinControls.UI.RadListControl radListControl1;
        private System.ComponentModel.BackgroundWorker backgroundWorker1;
        private Telerik.WinControls.UI.RadButton radButtonTest;
        private Telerik.WinControls.UI.RadButton radButtonStop;
    }
}

Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;
  
namespace RadListControl_LargsItems_CS
{
    public partial class Form1 : Form
    {
        private Boolean m_Continue = true;
  
        public Form1()
        {
            InitializeComponent();
        }
  
        private void Form1_Load(object sender, EventArgs e)
        {
            this.radListControl1.SelectionMode = SelectionMode.One;
            this.backgroundWorker1.RunWorkerAsync();
        }
  
  
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (m_Continue == true)
            
                radListControl1.Items.Add(DateTime.Now.ToString());
                if (radListControl1.Items.Count > 100)
                {
                    radListControl1.Items.RemoveAt(0);
                }
                this.backgroundWorker1.ReportProgress(0, radListControl1.Items.Count - 1);
                System.Threading.Thread.Sleep(1000);
            }
        }
  
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (m_Continue)
            { radListControl1.ScrollToItem(radListControl1.Items[Convert.ToInt32(e.UserState)]);}
        }
  
        private void radButtonTest_Click(object sender, EventArgs e)
        {
            MessageBox.Show("UI Still Responding");
        }
  
        private void radButtonStop_Click(object sender, EventArgs e)
        {
            m_Continue = false;
        }
  
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            m_Continue = false;
        }
  
    }
}

Let me know how that goes
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 10 Feb 2011, 11:37 PM
Hi,

Just a small updated Form1.cs to make it safer (so not to perform illegal cross thread operations).

Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;
  
namespace RadListControl_LargsItems_CS
{
    public partial class Form1 : Form
    {
        private Boolean m_Continue = true;
        public delegate void AddItemCallback(string text);
  
  
        public Form1()
        {
            InitializeComponent();
        }
  
        private void Form1_Load(object sender, EventArgs e)
        {
            this.radListControl1.SelectionMode = SelectionMode.One;
            this.backgroundWorker1.RunWorkerAsync();
        }
  
  
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (m_Continue == true)
            {
                radListControl1.Invoke(new AddItemCallback(this.AddItem), new object[] { DateTime.Now.ToString() });
                this.backgroundWorker1.ReportProgress(0, radListControl1.Items.Count - 1);
                System.Threading.Thread.Sleep(1000);
            }
        }
  
        private void AddItem(string text)
        {
            radListControl1.Items.Add(text);
            if (radListControl1.Items.Count > 100)
            {
                radListControl1.Items.RemoveAt(0);
            }
        }
  
  
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (m_Continue)
            { radListControl1.ScrollToItem(radListControl1.Items[Convert.ToInt32(e.UserState)]);}
        }
  
        private void radButtonTest_Click(object sender, EventArgs e)
        {
            MessageBox.Show("UI Still Responding");
        }
  
        private void radButtonStop_Click(object sender, EventArgs e)
        {
            m_Continue = false;
        }
  
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            m_Continue = false;
        }
  
    }
}

Richard
0
Richard Slade
Top achievements
Rank 2
answered on 14 Feb 2011, 11:32 AM
Hello,

Did this help? If so please remember to mark as answer. If you need further assistance, let me know
thanks
Richard
0
Ivan Petrov
Telerik team
answered on 16 Feb 2011, 11:06 AM
Hi Bibek,

Richard`s solution is working without any delay when you are adding up to about 100 items a second. From 100 items upwards there is some delay and when the garbage collector passes the delay in UI response time is increased.

I played with the solution and I was able to make the UI 100% responsive even when adding more than 500 items per second. What I did was to add a Queue<string> where the HTML-like text was stored and a Timer. On every tick of the timer an item is dequeued from the queue and is added to the RadListControl and if there are more than 100 items one is removed. However in this solution there is a potential risk of overflowing the queue, but if the average items add rate is not too high it should cope.

I have attached this modified solution for you to look at.

Another thing is that if you will be displaying that much of items per second they will be unreadable to the user. You might think of some mechanism for reducing the number of displayed items.

I hope we have been of help. If you need further assistance, do not hesitate to ask.

Kind regards,
Ivan Petrov
the Telerik team
Q3’10 SP1 of RadControls for WinForms is available for download; also available is the Q1'11 Roadmap for Telerik Windows Forms controls.
Tags
ListControl
Asked by
Bibek
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Ivan Petrov
Telerik team
Share this question
or