如何停止用于异步翻译图像的 Xamarin.Forms 行为?
How to stop a Xamarin.Forms behavior used to asynchronously translate an image?
在一个 Xamarin.Forms 项目中,我试图重复将图像从位置 A(x,y) 转换到位置 B(x,y) 并返回,从 B 到 A。到实现这一点,我读到可以自定义行为。
我扩展了行为 class,覆盖了 OnAttachedTo 和 OnDetachingFrom。在 OnAttachedTo 方法中,我启动了一个任务,该任务重复执行两种翻译。
这是我的行为class:
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 中的 Animated 设置为 false 且从不调用 OnDetachingFrom 时,属性 绑定不起作用。
我究竟做错了什么?有什么建议吗?
通过文档可以看出:
The OnDetachingFrom method is fired when the behavior is removed from
the control. This method receives a reference to the control to which
it is attached, and is used to perform any required cleanup. For
example, you could unsubscribe from an event on a control to prevent
memory leaks.
它只会在您从图像中删除行为时触发。我会给你一个关于如何停止动画的例子:
我在后面的代码里定义了一个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 预期,只需将 Animated 设置为 false :
protected override void OnDetachingFrom(Image image)
{
base.OnDetachingFrom(image);
Animated = false;
}
您可以将我的点击事件转换为您项目中的某些绑定并使其工作。
在一个 Xamarin.Forms 项目中,我试图重复将图像从位置 A(x,y) 转换到位置 B(x,y) 并返回,从 B 到 A。到实现这一点,我读到可以自定义行为。
我扩展了行为 class,覆盖了 OnAttachedTo 和 OnDetachingFrom。在 OnAttachedTo 方法中,我启动了一个任务,该任务重复执行两种翻译。
这是我的行为class:
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 中的 Animated 设置为 false 且从不调用 OnDetachingFrom 时,属性 绑定不起作用。 我究竟做错了什么?有什么建议吗?
通过文档可以看出:
The OnDetachingFrom method is fired when the behavior is removed from the control. This method receives a reference to the control to which it is attached, and is used to perform any required cleanup. For example, you could unsubscribe from an event on a control to prevent memory leaks.
它只会在您从图像中删除行为时触发。我会给你一个关于如何停止动画的例子:
我在后面的代码里定义了一个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 预期,只需将 Animated 设置为 false :
protected override void OnDetachingFrom(Image image)
{
base.OnDetachingFrom(image);
Animated = false;
}
您可以将我的点击事件转换为您项目中的某些绑定并使其工作。