WPF: Animating Popup opacity using Storyboard

252 Views Asked by At

I would like to animate a horizontal slide-in & fade combined with a Popup. The slide is implemented using DoubleAnimation on HorizontalOffset and works fine with no fade animation. Once we add the "fade" animation via PopupAnimation="Fade" then the slide-out stops working. I assume this is because "IsOpen" is now false and the popup has been removed (much the same way PopupAnimation="Slide" has no slide-out).

No problem, thinks I, I will just animate the Opacity manually, and animate "IsOpen" with a slight delay when closing.

I'm aware that we can't animate Opacity directly, as it's the child elements opacity that needs to be affected.

With this element:

                <local:AirspacePopup
                    x:Name="ControlsWindow"
                    ...
                    >
                    <Grid>
                        <Image Name="KeyMap" ... />
                    </Grid>
                    <local:AirspacePopup.Style>
                        <Style TargetType="local:AirspacePopup">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ShowViewControls}" Value="True">
                                    ...Animations go here

I've tried the following:

Binding directly to image - Has binding error

<DoubleAnimation
    Storyboard.Target="{Binding ElementName=KeyMap}"
    Storyboard.TargetProperty="Opacity"
    From="0" To="1" Duration="0:0:0.30" />

Bunding to popup children (aka WPF Animate property of child without using Name) - Has binding error

<DoubleAnimation
    Storyboard.Target="{Binding ElementName=ControlsWindow, Path=Children[0]}}"
    Storyboard.TargetProperty="Opacity"
    From="0" To="1" Duration="0:0:0.30" />

And creating a property in code-behind to forward the property to the children. No error, but breakpoint in C# is never hit

<DoubleAnimation
    Storyboard.TargetProperty="ChildOpacity"
    From="0" To="1" Duration="0:0:0.30" />
        public double ChildOpacity
        {
            get => Child.Opacity;
            set {
                SetValue(ChildOpacityProperty, value);
                Child.Opacity = value;
            }
        }

I'm all outta ideas - what haven't I tried yet?

NOTE: In case it's not clear, I'm very new (or rusty) in WPF

1

There are 1 best solutions below

0
FrozenKiwi On

I stumbled across an answer here: I can't animate a custom property in WPF

The property in the ViewModel -is- animated, just not via the accessors (?). Adding the OnPropertyChanged handler allows me to catch the change and react as appropriate

        public double ChildOpacity
        {
            get => Child.Opacity;
            set => SetValue(ChildOpacityProperty, value);
        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property == ChildOpacityProperty)
            {
                Child.Opacity = (double)e.NewValue;
            }
        }