Telerik blogs

Task-It Series

This post is part of a series of blog posts and videos about the Task-It (task management) application that I have been building with Silverlight 4 and Telerik's RadControls for Silverlight 4. For a full index of these resources, please go here. One of the posts listed in the index provides a full source download for the application, and I will be referring to that source code in this post.

Providing feedback to the user

In my last post I talked about using events to pass information from the RadTreeView to the RadGridView in the Tasks page in Task-It. In this post I'll talk about events that are used commonly in Task-It...ones that show and hide the Activity control every time a time consuming operation is in progress, like a call to the database, or the downloading of a XAP file. The Activity control is what shows the 'Please wait...' message.

Showing the Activity control has 2 benefits:

  • It gives feedback to the user that something is going on
  • It puts a semi-transparent full screen layer over the UI that prevents the user from clicking on things while an operation is in progress.

Activity control

Publishing the 'show' event

As I mentioned in the last post, when passing events via the MVVM Light Toolkit's Messenger class, one type of event can be distinguished from another by what type of arguments they pass. In this case, I'm going to pass OperationInProgressArgs.

public class OperationInProgressArgs
{
}

You're probably wondering if I forgot to include the code for the class. Nope, I didn't. There is nothing to it, no constructor, properties, nothing. But, if I fire an event where I'm passing this object type, I can listen for it wherever I want and respond accordingly. It doesn't have to pass any arguments, and in this case, there really aren't any arguments to pass.

I can't say for sure whether there is a better way of doing this with the MVVM Light Toolkit's Messenger class, but it's working for me, so for the time being I'm ok w/ passing a nothing.

Now this event is only fired from one place in the code...the Utils class that lives in the Core folder under the TaskIt project.

public static void ShowBusyIndicator()
{
    Messenger.Default.Send(new OperationInProgressArgs());
}

The reason I added this static method to the Utils class is so that I can do this everywhere in my code that I want to show the Activity control:

Utils.ShowBusyIndicator();

 

If you search the Task-It codebase you'll see that I do it in several places. You may also notice several cases where the code just says ShowBusyIndicator (without the preceding Utils.). This is a method that lives in the base class for the widgets that appear in the Dashboard and Help pages, because each of those widgets loads their data asynchronously, and so each widget gets its own Activity control.

Publishing the 'hide' event

Similarly, I have a method in the Utils class that can be used to listen for the event:

public static void HideBusyIndicator()
{
    Messenger.Default.Send(new OperationCompletedArgs());
}

 

And if we look at OperationCompletedArgs, we see once again that it is a blank class:

public class OperationCompletedArgs
{
}

So once again, from anywhere in the code I can hide the Activity control...when he data comes back from the database, the XAP finishes loading, etc.

Utils.HideBusyIndicator();

Listening for the show/hide events

So we've seen how the events are fired, but the listening part is what is actually going to show/hide the Activity control in the UI. The 'global' Activity control (not the ones used in widgets) lives in MainPage.xaml in the TaskIt project, so naturally the place to show/hide it is in that control's view model, MainPageViewModel, in the ViewModels folder under the Task-It project. In it's constructor we have these 2 lines:

Messenger.Default.Register<OperationInProgressArgs>(this, OnOperationInProgress);
Messenger.Default.Register<OperationCompletedArgs>(this, OnOperationCompleted);

So let's look at the methods that are called when the event is fired, OnOperationInProgress and OnOperationCompleted.

public void OnOperationInProgress(OperationInProgressArgs args)
{
    IsOperationInProgress = true;
}
 
public void OnOperationCompleted(OperationCompletedArgs args)
{
    IsOperationInProgress = false;
}

All they do is toggle the value of a bool property:

public bool IsOperationInProgress
{
    get { return _isOperationInProgress; }
    set { _isOperationInProgress = value; this.OnPropertyChanged(p => p.IsOperationInProgress); }
}

Remember that whenever the value of a property that is bound to a UI element changes, we need to call OnPropertyChanged or else the UI won't know about it, and nothing will happen.

And of course, the IsActive property of the Activity control (which determines whether it is shown or hidden is bound to this property:

<activity:Activity IsActive="{Binding IsOperationInProgress}" ActiveContent="{Binding ResourceMessagePleaseWait}"/>

Where to publish/subscribe?

Keep in mind that in the MVVM pattern, the view model is the brains of the operation, so these utility methods that show and hide the global Activity control should always be called from within the view model, not from code-behind.

Wrap up

So what we've got here is a simple event-based framework for doing something that needs to be done many times in the app, show and hide the Activity control. In my next post, I'll talk about what happens when an error occurs in between the showing and hiding of the Activity control.


Comments

Comments are disabled in preview mode.