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

Loading Data Animation

3 Answers 1009 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Andreas Haeusler
Top achievements
Rank 2
Andreas Haeusler asked on 22 Jul 2013, 11:04 AM
Hello,

is there a simple way to show a "Loading Data" animation when asynchroniously fetching data?
In our application we create a RadTabPage with detailed information about a previously double clicked GridViewItem. This RadTabPage contains an empty RadGridView bound to a properly typed DataBindingsource. Until the data was successfully fetched from our database -- which can be time consuming -- the end user only sees this empty grid.

To communicate to the user that some data will appear, it would be great to overlay the grid with a spinner animation or some textual hint.

We would prefer a generic approach which only affects the GridView itself so that it can be wrapped into an extension method or extended class.


Kind regards,
Andreas Haeusler

3 Answers, 1 is accepted

Sort by
0
George
Telerik team
answered on 24 Jul 2013, 03:18 PM
Hi Andreas,

Thank you for writing.

There are a few available approaches in your case:
  1. Use a picturebox which can be added to the controls of the grid and position it in the center of the grid. It can be easily toggled to visible and invisible at any given time. Also supports gif images.
  2. Draw the picture directly on top the grid. This approach does not support gif images.
  3. Set the image to the TableElement of the grid. Gifs are supported however the image will stay below the rows, this approach is useful if you are sure that the image will appear only when there are no rows. Additionally this approach requires the least tuning and code.
I have created a sample project which demonstrates these three possibilities. I have used asynchronous method to recreate a real situation, this should help you decide which approach fits your needs best. Please refer to the attached project.

I hope this helps, if you have any other questions or comments, please let me know.
 
Regards,
George
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Andreas Haeusler
Top achievements
Rank 2
answered on 24 Jul 2013, 07:09 PM
Thank you George!

The approach using TableElement.Image proved to be the one of choice!

I modified my initial version (using a picturebox) and attached it to this post. It contains a custom RadGridView boasting a new method LoadDataAsync(ObjectContext, ProcedureName,params[]) which asynchronously populates the grid with data (showing the loading animation) using an entity framework ObjectContext.
In case of timeouts or connectivity problems it even allows to retry the data fetching by painting a retry button in place.

I hope someone finds it useful.


Thanks again,
Andreas



using System;
using System.Data.Objects;
using System.Threading;
using System.Windows.Forms;
using CustomControlCollection.Properties;
using Telerik.WinControls.UI;
 
namespace CustomControlCollection
{
    public class CustomRadGridView : RadGridView
    {
       
        
 
        public override string ThemeClassName
        {
            get { return typeof(RadGridView).FullName; }
        }
 
       
 
        #region asynchronous loading of data
 
        new public object DataSource  // hide default setter to force either Sync or Async
        {
            get { return base.DataSource; }
            private set { base.DataSource = value; }  // if you really want to set this synchronously use DataSourceSync!
        }
 
        public object DataSourceSync // synchronous setter
        {
            set { base.DataSource = value; }
        }
 
        // delegate and event to notify application of completed data loading process
        public delegate void DataLoadedAsyncHandler(object sender);
        public event DataLoadedAsyncHandler DataLoadedAsync;
 
 
 
 
 
        private readonly RadButton _retryButton = new RadButton { Text = @"Retry", Dock = DockStyle.Fill };
        private readonly RadLabel _retryLabel = new RadLabel { Dock = DockStyle.Fill };
        private string _methodName;
        private object[] _params;
        private Type _objectContextType;
        private readonly System.Drawing.Bitmap _loadingAnimation = Resources.spin_24x24_loading;
 
 
        private void RetryButtonOnClick(object sender, EventArgs eventArgs)
        {
            ToggleRetryButton();
            StartDataFetchingThread();
        }
 
        /// <summary>
        /// Gets data by stored procedure or function call on an objectcontext
        /// </summary>
        /// <param name="exemplaryContext">exemplary instance of the objectcontext to use... a new instance will be created and used</param>
        /// <param name="methodName">Name of the sproc or udf to call</param>
        /// <param name="parameters">parameters for the sproc or udf</param>
        public void LoadDataAsync(ObjectContext exemplaryContext, string methodName, object[] parameters)
        {
            _retryButton.Click -= RetryButtonOnClick;
            _retryButton.Click += RetryButtonOnClick;
            _methodName = methodName;
            _params = parameters;
            _objectContextType = exemplaryContext.GetType();
            StartDataFetchingThread();
        }
 
        private void StartDataFetchingThread()
        {
            var thread = new Thread(FetchData) { IsBackground = true };
            thread.Start();
        }
 
        private void FetchData()
        {
 
            this.InvokeIfRequired(c => ToggleTableElementImage());
 
            if (_objectContextType != null)
            {
                var cont = Activator.CreateInstance(_objectContextType);
                var methodInfo = _objectContextType.GetMethod(_methodName);
                try
                {
                    object result = methodInfo.Invoke(cont, _params);
                    this.InvokeIfRequired(c =>
                    {
                        DataSource = result;
                    });
 
                }
                catch (Exception e) // something went wrong... show retry button
                {
                    this.InvokeIfRequired(c =>
                    {
                        ToggleTableElementImage();
                        ToggleRetryButton(e.Message);
                    });
                    return;
                }
            }
 
            this.InvokeIfRequired(c =>
            {
                if (DataLoadedAsync != null) DataLoadedAsync(this);
                ToggleTableElementImage();
            });
        }
 
        private void ToggleTableElementImage()
        {
            TableElement.Image = TableElement.Image == null ? _loadingAnimation : null;
        }
 
        private void ToggleRetryButton(string errorDescription = null)
        {
            if (Parent.Controls.Contains(_retryButton))
            {
                Parent.Controls.Remove(_retryButton);
                Parent.Controls.Remove(_retryLabel);
                return;
            }
            int controlIndex = Parent.Controls.GetChildIndex(this); // locate the radgrid position
            _retryLabel.Text = errorDescription;
            Parent.Controls.Add(_retryLabel);
            Parent.Controls.SetChildIndex(_retryLabel, controlIndex++);
            Parent.Controls.Add(_retryButton);
            Parent.Controls.SetChildIndex(_retryButton, controlIndex);
        }
 
 
 
 
        #endregion
 
      
    }
}

0
George
Telerik team
answered on 29 Jul 2013, 03:44 PM
Hi Andreas,

Thank you for posting your solution in our forums. I am sure someone will benefit from it.

If you have any other questions or comments, please let me know.
 
Regards,
George
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
GridView
Asked by
Andreas Haeusler
Top achievements
Rank 2
Answers by
George
Telerik team
Andreas Haeusler
Top achievements
Rank 2
Share this question
or