Introduction

When you execute a query or a web service, the application may take time to retrieve and display datas.

In order to avoid empty screen and indicate that an operation is ongoing, you can insert a progress control as a busy indicator in the page of the application. It provides feedback to the user that a long-running operation is underway.

Universal Windows App contains two progress controls : ProgressRing and ProgressBar.

But what if you want to create your own progress indicator?

That's why in this Wiki, we will see how to create a custom progress indicator?

 

Create a custom progress indicator

 

Create a new Universal Windows App project

  • Open Visual Studio and create a new Universal Windows App: MyProgressIndicatorApp




Declare Dependencies Properties

  •       Add a new class in the project and name it BusyIndicator. BusyIndicator will be the name of the custom progress control.
  •       Insert the following code in the BusyIndicator class:

/// <summary>
    ///     Custom control used to display a busy indication
    /// </summary>
    [TemplateVisualState(Name = "IsBusyState", GroupName = "BusyStatesGroup")]
    [TemplateVisualState(Name = "NormalState", GroupName = "BusyStatesGroup")]
    public class BusyIndicator : Control
    {
        #region Fields
 
        //Data
        private Boolean _isLoaded;
 
        #endregion
 
        #region DPs
 
        /// <summary>
        ///     DP definition for BusyProgressValue property
        /// </summary>
        public static readonly DependencyProperty BusyMessageProperty = DependencyProperty.Register("BusyMessage",
                                                                                                    typeof(String),
                                                                                                    typeof(BusyIndicator),
                                                                                                    new PropertyMetadata(String.Empty));
 
        /// <summary>
        ///     DP definition for BusyProgressValue property
        /// </summary>
        public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register("IsBusy",
                                                                                               typeof(Boolean),
                                                                                               typeof(BusyIndicator),
                                                                                               new PropertyMetadata(false,
                                                                                                                    OnIsBusyPropertyChanged));
 
        #endregion
 
        #region Constructors
 
        /// <summary>
        ///     Initialize a new instance of <see cref="BusyIndicator" />
        /// </summary>
        public BusyIndicator()
        {
            Loaded += OnLoaded;
            Unloaded += OnUnloaded;
        }
 
        #endregion
 
        #region Properties
 
 
        /// <summary>
        ///     Gets or sets if we are busy or not
        /// </summary>
        public Boolean IsBusy
        {
            get
            {
                return (Boolean)GetValue(IsBusyProperty);
            }
            set
            {
                SetValue(IsBusyProperty,
                         value);
            }
        }
 
        /// <summary>
        ///     Gets or sets the current busy message to display
        /// </summary>
        public String BusyMessage
        {
            get
            {
                return (String)GetValue(BusyMessageProperty);
            }
            set
            {
                SetValue(BusyMessageProperty,
                         value);
            }
        }
 
        #endregion
 
        #region Handlers
 
        private static void OnIsBusyPropertyChanged(DependencyObject d,
                                                    DependencyPropertyChangedEventArgs e)
        {
            var indicator = d as BusyIndicator;
 
            if ((indicator != null) && (indicator._isLoaded))
            {
                VisualStateManager.GoToState(indicator,
                                             indicator.IsBusy
                                                 ? "IsBusyState"
                                                 : "NormalState",
                                             true);
            }
        }
 
        private void OnLoaded(object sender,
                              RoutedEventArgs e)
        {
            _isLoaded = true;
            VisualStateManager.GoToState(this,
                                         IsBusy
                                             ? "IsBusyState"
                                             : "NormalState",
                                         true);
        }
 
        private void OnUnloaded(object sender,
                                RoutedEventArgs e)
        {
            VisualStateManager.GoToState(this,
                                         "NormalState",
                                         false);
        }
 
        #endregion
    }


The BusyIndicator inherits from Control.

As you can see we defined two properties BusyMessage and IsBusy

The BusyMessage contains the message will be displayed in the custom progress indicator BusyIndicator.

The IsBusy property contains the state (IsActive value) of the custom progress indicator BusyIndicator.

Now, let’s define the template of our custom progress indicator BusyIndicator.


Define the Template

  •        Open the App.xaml and insert the following code: 

<Application
    x:Class="MyProgressIndicatorApp.App"
    xmlns:local="using:MyProgressIndicatorApp"
    RequestedTheme="Light">
    <Application.Resources>
        <ResourceDictionary>
 
            <!--COLORS-->
            <Color x:Key="DarkBlue">#3B5998</Color>
 
            <!--BRUSHES-->
            <SolidColorBrush x:Key="DarkBlueBrush"
                             Color="{StaticResource DarkBlue}" />
             
            <Style x:Key="ProgressIndicatorStyle"
                   TargetType="local:BusyIndicator">
                <Setter Property="RequestedTheme"
                        Value="Light" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="local:BusyIndicator">
                            <StackPanel VerticalAlignment="Center"
                                        HorizontalAlignment="Center"
                                       >
                                <ProgressRing IsActive="{TemplateBinding IsBusy}"
                                              Foreground="{StaticResource DarkBlueBrush}"
                                              Height="70"
                                              Width="70" />
 
                                <TextBlock Text="{TemplateBinding BusyMessage}"
                                           Foreground="{StaticResource DarkBlueBrush}"
                                           HorizontalAlignment="Center"
                                           Margin="0 10 0 0" />
                            </StackPanel>
 
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>


Our template contains a ProgressRing and a TextBlock.

Therefore you can custom as you like your template inside the ControlTemplate.

Use the custom progress indicator

  •          Open the MainPage.xaml and insert the following code:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <local:BusyIndicator IsBusy="True"
                             Style="{StaticResource ProgressIndicatorStyle}"
                             BusyMessage="Downloading"
                             Height="300"
                             Width="300" />
    </Grid>


·         Launch the application MyProgressIndicatorApp, you can use the Visual Studio shortcut F5.




Conclusion


In this Wiki, we saw how it is easy to create a custom progress indicator for your Universal Windows App.

Download


You can download all project in this link : https://gallery.technet.microsoft.com/UWP-Custom-progress-control-6f75c51a

See Also