jeudi 10 octobre 2019

Building a SMARTER Placeholder Loading UI 2.0 using only C# for your UWP application [C#,Storyboard]

Previously to build my Placeholder UI I would be using a UserControl, that contained Grid, Storyboard, adding a gradient styling and a ContentControl.
However this could be quite resource intensive which is not great and also I was not happy with my initial implementation.

After a quick refactoring it was decided that a blinking rectangle would better fit the need and we would not need to have to animate something going to left to right.





To make things simple it was decided to create a new Class that would inherited from Grid:

public class PlaceholderSkeletonView : Grid

Next we just needed to add a Storyboard animation that will make this element "blink"

var blinkAnimation = new DoubleAnimation()
    {
         From = 1,
         To = 0.4,
         AutoReverse = true,
         //blink every 1sec
         Duration = new Windows.UI.Xaml.Duration(TimeSpan.FromSeconds(1)),
         RepeatBehavior = RepeatBehavior.Forever
    };

And lastly all we need is to add this blinking animation to our Storyboard:

 myLoadingStoryboard.Children.Add(blinkAnimation);

 Storyboard.SetTarget(myLoadingStoryboard, this);
 Storyboard.SetTargetProperty(blinkAnimation, "Opacity");

 Loaded += (a, e) => myLoadingStoryboard.Begin();

All in all it was


Full class here:


public class PlaceholderSkeletonView : Grid
{
        Storyboard myLoadingStoryboard { get; set; }
        public PlaceholderSkeletonView()
        {            
            myLoadingStoryboard = new Storyboard();
            var blinkAnimation = new DoubleAnimation()
            {
                From = 1,
                To = 0.4,
                AutoReverse = true,
                //blink every 1sec
                Duration = new Windows.UI.Xaml.Duration(TimeSpan.FromSeconds(1)),
                RepeatBehavior = RepeatBehavior.Forever
            };

            myLoadingStoryboard.Children.Add(blinkAnimation);

            Storyboard.SetTarget(myLoadingStoryboard, this);
            Storyboard.SetTargetProperty(blinkAnimation, "Opacity");

            Loaded += (a, e) => myLoadingStoryboard.Begin();
        }
}


In your XAML it would look as follows for example:


<StackPanel Orientation="Horizontal">
     <local:PlaceholderSkeletonView
                Width="120"
                Height="120"
                Margin="20"
                Background="#ebebeb" />
          <StackPanel Margin="20" Orientation="Vertical">
                <local:PlaceholderSkeletonView
                       Width="190"
                       Height="20"
                       Margin="10"
                       Background="#ebebeb" />
                <local:PlaceholderSkeletonView
                       Width="150"
                       Height="20"
                       Margin="10"
                       Background="#ebebeb" />
                <local:PlaceholderSkeletonView
                       Width="120"
                       Height="20"
                       Margin="10"
                       Background="#ebebeb" />
           </StackPanel>
</StackPanel>


Happy Coding!

Github repo:  https://github.com/Delaire/UIPlaceholder