Using RadListControl to display rolling items

5 posts, 0 answers
  1. Bibek
    Bibek avatar
    7 posts
    Member since:
    Dec 2008

    Posted 10 Feb 2011 Link to this post

    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

  2. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 10 Feb 2011 Link to this post

    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
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 10 Feb 2011 Link to this post

    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
  5. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 14 Feb 2011 Link to this post

    Hello,

    Did this help? If so please remember to mark as answer. If you need further assistance, let me know
    thanks
    Richard
  6. Ivan Petrov
    Admin
    Ivan Petrov avatar
    701 posts

    Posted 16 Feb 2011 Link to this post

    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.
Back to Top
UI for WinForms is Visual Studio 2017 Ready