如何停止用于异步转换图像的Xamarin.Forms行为?

如何停止用于异步转换图像的Xamarin.Forms行为?,xamarin.forms,mvvmcross,behavior,Xamarin.forms,Mvvmcross,Behavior,在一个Xamarin.Forms项目中,我试图反复将图像从位置Ax,y转换为位置Bx,y,然后再从B转换为a。为了实现这一点,我阅读了一篇可以自定义行为的文章 我扩展了行为类,覆盖了OnAttachedTo和OnDeachingFrom。在OnAttachedTo方法中,我启动了一个任务,该任务重复执行这两个翻译 这是我的行为课: public class MoveImageBehavior : Behavior<Image> { private Image _Image =

在一个Xamarin.Forms项目中,我试图反复将图像从位置Ax,y转换为位置Bx,y,然后再从B转换为a。为了实现这一点,我阅读了一篇可以自定义行为的文章

我扩展了行为类,覆盖了OnAttachedTo和OnDeachingFrom。在OnAttachedTo方法中,我启动了一个任务,该任务重复执行这两个翻译

这是我的行为课:

public class MoveImageBehavior : Behavior<Image>
{
    private Image _Image = null;

    public static readonly BindableProperty AnimatedProperty = BindableProperty.Create("Animated", typeof(bool), typeof(ImageAnimatedBehavior), defaultValue: false);
    public bool Animated
    {
        get { return (bool)GetValue(AnimatedProperty); }
        set { SetValue(AnimatedProperty, value); }
    }

    protected override void OnAttachedTo(Image image)
    {
        base.OnAttachedTo(image);

        _Image = image;
        Animated = true;
        Task.Run(AnimateImage);
    }

    protected override void OnDetachingFrom(Image image)
    {
        base.OnDetachingFrom(image);
        _Image = null;
    }

    private async void AnimateImage()
    {
        while (_Image != null && Animated)
        {
            await _Image.TranslateTo(100, 100, 1000);
            await _Image.TranslateTo(0, 0, 1000);
        }
    }
}
xaml文件中的图像:

<ContentView>
    <Grid>
        <Image x:Name="image_translating" Source="my_icon" Aspect="AspectFit">
            <Image.Behaviors>
                <behaviors:MoveImageBehavior Animated="{Binding ImageTranslating}" BindingContext="{Binding BindingContext, Source={x:Reference image_translating}}"/>
            </Image.Behaviors>
        </Image>
    </Grid>
</ContentView>
图像重复正确地翻译为我想要的,但我无法停止while例程。如果在ViewModel中将“动画”设置为false,并且从不调用OnDetachingFrom,则属性绑定将不起作用。
我做错了什么?有什么建议吗?

通过文档,我们可以看到:

当从中删除行为时,将激发OnDetachingFrom方法 控制。此方法接收对要访问的控件的引用 它是附着的,用于执行任何所需的清理。对于 例如,您可以取消订阅控件上的事件以防止 内存泄漏

仅当您从图像中删除该行为时,它才会被激发。我将给您一个关于如何停止动画的示例:

private void Button_Clicked(object sender, EventArgs e)
{
    showA = !showA;

    if (showA)
    {
        image_translating.Behaviors.Add(new MoveImageBehavior());

    }
    else
    {
        var toRemove = image_translating.Behaviors.FirstOrDefault(b => b is MoveImageBehavior);
        if (toRemove != null)
        {
            image_translating.Behaviors.Remove(toRemove);
        }
    }
}
我在代码隐藏中定义了一个bool属性来控制停止或不停止:

  public bool showA  = true;
我添加了一个按钮作为停止动画的示例:

private void Button_Clicked(object sender, EventArgs e)
{
    showA = !showA;

    if (showA)
    {
        image_translating.Behaviors.Add(new MoveImageBehavior());

    }
    else
    {
        var toRemove = image_translating.Behaviors.FirstOrDefault(b => b is MoveImageBehavior);
        if (toRemove != null)
        {
            image_translating.Behaviors.Remove(toRemove);
        }
    }
}
另外,在OnDetachingFrom方法中,不要将图像设置为null,这将导致null预期,只需将动画设置为false:

protected override void OnDetachingFrom(Image image)
{
    base.OnDetachingFrom(image);
    Animated = false;
}
您可以将我的单击事件转换为项目中的某个绑定并使其工作

参考: