Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / WPF

WPF Loading Splash Screen

Rate me:
Please Sign up or sign in to vote.
4.83/5 (27 votes)
9 Oct 2010CPOL3 min read 166.7K   18.9K   63   16
Simple animated loading text, like last MSN messenger, show animation and transparent mask in WPF
main.jpg

Introduction

In the last version of MSN messenger, you can notice simple animated text loading when you login to your account. I tried to make something similar to make the application loading look professional.

Step by Step

Create Splash Window

Add a new window to your WPF application. You can call it Splashwindow, to make the window borderless and top most you need to add some properties as follows by adding to XAML in window tag or by using property panel.

XML
WindowStyle="None" WindowStartupLocation="CenterScreen" 
	ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"

Change BackGround

By default, the new window content contains a grid. We can change the grid background using linear gradient brush by adding the following code:

XML
<Grid.Background>
           <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
               <GradientStop Color="#FFB9BBFF" Offset="0" />
               <GradientStop Color="White" Offset="1" />
               <GradientStop Color="White" Offset="0.72" />
           </LinearGradientBrush>
       </Grid.Background>

It will look like this:

intial.jpg

Add Opacity Mask

To make effect of fading, we need to create a second grid to cover the lower half of the window with opacity mask. That will lead to fading effect when the text moves from the border to the center of the grid, the mask will be transparent in the lower and upper part of the second grid, and adding text to the grid to display the loading message, the sequence of display is moved from down to the middle with the new text then moving to the top to hide.

The following code of XAML creates the masked grid with text box:

XML
<Grid VerticalAlignment="Bottom" HorizontalAlignment="Stretch"
   Height="150" Background="#00FFFFFF">
           <Grid.OpacityMask>
               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                   <GradientStop Color="#00000000" Offset="0.283"/>
                   <GradientStop Color="#00000000" Offset="0.778"/>
                   <GradientStop Color="White" Offset="0.491"/>
               </LinearGradientBrush>
           </Grid.OpacityMask>
           <TextBlock x:Name="txtLoading" TextAlignment="Left"
       FontSize="16" FontWeight="Normal"  Foreground="#FF052045"
       Text="Beta 0.9"  TextWrapping="Wrap" VerticalAlignment="Bottom"
       HorizontalAlignment="Right" Width="421" >
           <TextBlock.Effect>
    <DropShadowEffect BlurRadius="6" Color="#FF797979" Direction="201"
       Opacity="0.68" ShadowDepth="3" />
               </TextBlock.Effect>
           </TextBlock>
       </Grid>

The grid background value is =#00FFFFFF which is completely transparent. We don't need to show the grid but without background, the mask will not work. You can notice in the previous XAML that the textblock has shadow effect.

In design view, it will look like this:

masked.jpg

Create Animation

In WPF, you can define animation. You don't need to write it yourself. In Microsoft Blend, just add a new storyboard and define key frames and make change like Flash but WPF will generate a readable format for animation. The animation will be defined in window resources tag and accessed by key. The following code shows two storyboards, each one having a one second duration, just change the bottom margin of textblock to move from the hidden region to visible according to opacity mask and vice versa.

XML
<Window.Resources>
        <Storyboard x:Key="showStoryBoard">
            <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty=
		"(FrameworkElement.Margin)" Storyboard.TargetName="txtLoading">
                <EasingThicknessKeyFrame KeyTime="0:0:0" Value="0,0,0,0"/>
                <EasingThicknessKeyFrame KeyTime="0:0:1" Value="0,0,0,70"/>
            </ThicknessAnimationUsingKeyFrames>
        </Storyboard>
        
        <Storyboard x:Key="HideStoryBoard">
            <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty=
		"(FrameworkElement.Margin)" Storyboard.TargetName="txtLoading">
                <EasingThicknessKeyFrame KeyTime="0:0:0" Value="0,0,0,70"/>
                <EasingThicknessKeyFrame KeyTime="0:0:1" Value="0,0,0,150"/>
            </ThicknessAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>

Working with Code Behind

Now we have created what we need in XAML. In code behind, we will create a thread to do loading work and make animation to the text, first we need to access animation, define two storyboard objects to access window resources storyBoards.

C#
Storyboard Showboard;
Storyboard Hideboard;

To access the window resource by the following code, just after InitializeComponent() call:

C#
Showboard = this.Resources["showStoryBoard"] as Storyboard;
Hideboard = this.Resources["HideStoryBoard"] as Storyboard;

Create two functions - one to show the text and one to hide as follows:

C#
 private void showText(string txt)
       {
           txtLoading.Text = txt;
           BeginStoryboard(Showboard);
       }
private void hideText()
       {
           BeginStoryboard(Hideboard);
       }

We need to create delegate for each function to enable calling form the loading thead as follows:

C#
private void load()
      {
          Thread.Sleep(1000);
          this.Dispatcher.Invoke(showDelegate, "first data to loading");
          Thread.Sleep(2000);
          //do some loading work
          this.Dispatcher.Invoke(hideDelegate);

          Thread.Sleep(2000);
          this.Dispatcher.Invoke(showDelegate, "second data loading");
          Thread.Sleep(2000);
          //do some loading work
          this.Dispatcher.Invoke(hideDelegate);

          Thread.Sleep(2000);
          this.Dispatcher.Invoke(showDelegate, "last data loading");
          Thread.Sleep(2000);
           //do some loading work
          this.Dispatcher.Invoke(hideDelegate);

          //close the window
          Thread.Sleep(2000);
          this.Dispatcher.Invoke(DispatcherPriority.Normal,
      (Action)delegate() { Close(); });
      }

Displaying the Splash

There are many ways to display the splash screen, but the simplest way I think is just add the following after InitializeComponent in main window:

C#
new SplashWindow().ShowDialog();

I hope you found that useful.

Points of Interest

The main point is using of opacity mask and accessing storyboard form code behind, and the power of animation in WPF.

History

  • 10th October, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer hlogic
Egypt Egypt
work mainly with microsoft .net technology ,not because it is the better ,but it is growing rapidly and take advantages of other technologies, i don't hate java but it is not my first choice.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Monir Sabbagh9-Mar-12 19:23
Monir Sabbagh9-Mar-12 19:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.