Search code examples
user-controlsstoryboardborderwinui-3winui

How to Animate a Border Brush opacity


How do I set a storyboard to animate the opacity of a Border.BorderBrush. I want to create a DashBoard control where the control is surrounded by a 'Pulsing' border ie the opacity of the border changes from visible to invisible and then back to visible over a time period of say 3 seconds.

I have created a storyboard that will do this and applied it to the border but the entire contents of the border ie the whole user control is affected and not just the border's outline.

    <UserControl.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation Storyboard.TargetName="MyAnimatedBorder" Storyboard.TargetProperty="(BorderBrush.Opacity)"
                             From="1.0" To="0.0"
                             Duration="0:0:3" AutoReverse="True"
                             RepeatBehavior="Forever" />
        </Storyboard>
    </UserControl.Resources>


    <Border  x:Name="MyAnimatedBorder" BorderThickness="6" Margin="10">
        <Border.BorderBrush  >
            Silver
        </Border.BorderBrush>
    </Border>
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        myStoryboard.Begin();
    }

Solution

  • You can workaround this by separating the Border:

    AnimatedBorderUserControl.xaml

    <UserControl
        x:Class="WinUIApp.AnimatedBorderUserControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="using:WinUIApp"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <UserControl.Resources>
            <Storyboard x:Name="AnimatedBorderStoryboard">
                <DoubleAnimation
                    AutoReverse="True"
                    RepeatBehavior="Forever"
                    Storyboard.TargetName="AnimatedBorder"
                    Storyboard.TargetProperty="Opacity"
                    From="0"
                    To="1"
                    Duration="0:0:1" />
            </Storyboard>
        </UserControl.Resources>
    
        <Grid>
            <Border
                x:Name="AnimatedBorder"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                BorderBrush="{x:Bind BorderBrush, Mode=OneWay}"
                BorderThickness="{x:Bind BorderThickness, Mode=OneWay}"
                CornerRadius="{x:Bind CornerRadius, Mode=OneWay}" />
            <TextBlock
                Margin="{x:Bind BorderThickness, Mode=OneWay}"
                Text="Animated Border" />
        </Grid>
    
    </UserControl>
    

    AnimatedBorderUserControl.xaml.cs

    using Microsoft.UI.Xaml.Controls;
    
    namespace WinUIApp;
    
    public sealed partial class AnimatedBorderUserControl : UserControl
    {
        public AnimatedBorderUserControl()
        {
            InitializeComponent();
            Loaded += AnimatedBorderUserControl_Loaded;
        }
    
        private void AnimatedBorderUserControl_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
        {
            AnimatedBorderStoryboard.Begin();
        }
    

    Then use it like this:

    <local:AnimatedBorderUserControl
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        BorderBrush="SkyBlue"
        BorderThickness="1" />