简体   繁体   中英

How to create a FadeTo() animation based on BindableProperty change, MVVM style?

Let's say I have a view, with an <Image> element in it, that is visible based on whether it has a non-null property or not in the viewmodel. Like this:

<Image IsVisible="{Binding HasPhoto}" Source="{Binding Url}" />

With this ViewModel (only copied the relevant part):

private string url {get;set;}
public string Url {
    get => url;
    set {
        url = value;
        OnPropertyChanged(nameof(HasPhoto));
        OnPropertyChanged();
    }
}

public bool HasPhoto { get => Url != null; }

And somewhere in the ViewModel, I set: Url = null . This will cause HasPhoto to become false, and immediately render the <Image> element invisible, leaving no room to animate with .FadeTo(0) in the behavior. This is my current behavior implementation:

public class FadingBehavior : Behavior<VisualElement>
{
    public uint FadeTime { get; set; } = 250;

    protected override void OnAttachedTo(VisualElement bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.PropertyChanged += VisibilityMightHaveChanged;
    }

    protected override void OnDetachingFrom(VisualElement bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.PropertyChanged -= VisibilityMightHaveChanged;
    }

    private void VisibilityMightHaveChanged(object sender, PropertyChangedEventArgs args)
    {
        var element = sender as VisualElement;
        if (args.PropertyName == VisualElement.IsVisibleProperty.PropertyName)
        {
            var fadeToValue = element.IsVisible ? 1 : 0;

            element.Opacity = -fadeToValue + 1;
            element.FadeTo(fadeToValue, FadeTime);
        }
    }
}

This is fine, when the the <Image> becomes visible, because first it becomes visible, then it fades from 0 opacity to 1. But, for fading out this is not good, as the Url is removed instantly, rendering the image empty and invisible, so the fade-out animation cannot even start.

What is a good way to create an animation based on a bindable property value change?

I think that you are not far from a good solution.

What I would do is to inherit from Image and create FadableImage with bindable property called something like VisibilityHelper . Then when you assign the value to it the Image will still be visible and you can initiate the animation in a way that you already do. Just in the end when animation completes you should check the value of VisibilityHelper and if it is still the same also set IsVisible to the appropriate value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM