Creating custom indicator in Silverlight


In this post we will see how to create a custom indicator in Silverlight. This indicator can be used if your application is waiting for any responses. Suppose saving data in database.

Purpose:

If you are working in a slow network environment and if your operation is waiting for server responses then as a user you might wondering what is happening in the back ground. Without a correct indicator you might think that your system has stuck and you might close your window. Thus we need some sort of indicator to ask user to wait.

Creating the xaml:

Delete the Layout root and create the story board:

<UserControl.Resources>            
    <Storyboard x:Name="BlinkAnimation" RepeatBehavior="Forever">                    
        <ColorAnimationUsingKeyFrames
                BeginTime="00:00:00"
                Storyboard.TargetName="__txtInformation"
                Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
            <EasingColorKeyFrame KeyTime="00:00:01" Value="#FFFA0000"/>                
            <EasingColorKeyFrame KeyTime="00:00:02" Value="#FFFAE300"/>                
            <EasingColorKeyFrame KeyTime="00:00:03" Value="#FF00FA1C"/>                
            <EasingColorKeyFrame KeyTime="00:00:04" Value="#FF0C00FA"/>            
        </ColorAnimationUsingKeyFrames>                
    </Storyboard>        
</UserControl.Resources>    
<Grid x:FieldModifier="private" x:Name="__txtInformation" Margin="20,0,0,0" VerticalAlignment="Center"  Background="Black" >                
    <TextBlock x:FieldModifier="private"  Margin="10,2,10,2"  x:Name="__statusMessage"
                        VerticalAlignment="Center"
                        Text="Status Message"
                Foreground="White"/>
    </Grid>

Creating the Code Behind:

Create the property status message.This message will be displayed to the user:

public string Text

 {

   get { return __statusMessage.Text; }

   set { __statusMessage.Text = value; }

 }

Begin the story board:

public void StartTick(string Text)

{

  __statusMessage.Text = Text;

  if (BlinkAnimation.GetCurrentState() == ClockState.Stopped)

   {

     BlinkAnimation.Begin();

 

    }

     this.Visibility = Visibility.Visible;

 }

Stop the story board:

public void StopTick()

{

  if (BlinkAnimation.GetCurrentState() != ClockState.Stopped)

  {

     BlinkAnimation.Stop();

     this.Visibility = Visibility.Collapsed;

   }

}

Give the user two options to use the status indicator for more flexibility:

 Dictionary<intstring> _dictMessages = new Dictionary<intstring>();

public void StartWait(int MessageID, bool Wait, string format, params object[] args)

{

    string message = string.Format(format, args);

    this.Visibility = Visibility.Visible;

    this.BlinkAnimation.Begin();

    if (!_dictMessages.ContainsKey(MessageID))

    {

        _dictMessages.Add(MessageID, message);

    }

    __statusMessage.Text = collectMessages();

    if (Wait)

    {

        disableTop(false);

    }

}

public void StartWait(int MessageID, string format, params object[] args)

{

    StartWait(MessageID, true, format, args);

}

To Stop the indicator:

public void StopWait(int MessageID)

{

    if (_dictMessages.ContainsKey(MessageID))

    {

        _dictMessages.Remove(MessageID);

   }

   disableTop(true);

   string message = collectMessages();

   if (string.IsNullOrEmpty(message))

   {

       this.Visibility = Visibility.Collapsed;

       this.BlinkAnimation.Stop();

   }

   __statusMessage.Text = message;

}

Utility Methods:

private void disableTop(bool which)

{

    FrameworkElement el = this;

    FrameworkElement oldel = null;

    while (el != null)

    {

        oldel = el;

        el = (FrameworkElement)el.Parent;

        if (el is Liquid.Dialog)

            break;

    }

    if (oldel != null)

    {

        oldel.IsHitTestVisible = which;

    }

}

private string collectMessages()

{

    List<string> messages = new List<string>();

    foreach (string s in _dictMessages.Values)

    {

        messages.Add(s);

    }

    return string.Join("/", messages.ToArray());

}

Using the Status Indicator:

Put the Status Indicator in the correct position:

<my:BlinkingStatus Grid.Column="2" x:Name="__statusIndicator"></my:BlinkingStatus>

Now in the code when you are starting any heavy duty operation such as database fetching call the Start wait method:

__statusIndicator.StartWait(1, true"Saving data. Please wait...");

Here the message id is 1. This is very important. Suppose simultaneously you are fetching another database and also waiting that operation to be completed then it might happen to status indication are running in the back ground. In those cases the message id is very important.

__statusIndicator.StartWait(2, true"Updating data. Please wait..."); 

After the database operation stop the indicator :

__statusIndicator.StopWait(1);(message id=1) 

That's it. Thanks.

Up Next
    Ebook Download
    View all
    Learn
    View all