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
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
0
Hi Andreas,
Thank you for writing.
There are a few available approaches in your case:
George
Telerik
Thank you for writing.
There are a few available approaches in your case:
- 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.
- Draw the picture directly on top the grid. This approach does not support gif images.
- 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,I hope this helps, if you have any other questions or comments, please let me know.
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 >>
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
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
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
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 >>
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 >>