【发布时间】:2015-07-30 20:04:39
【问题描述】:
我想使用情节提要动画逐渐将 WPF 元素的可见性变为隐藏,并等待它完成,然后再继续编写代码。但是,我不想使用Storyboard.Completed 属性转到不同的函数,因为它需要传递给它的参数,而且它会增加复杂性。
我想它是这样工作的:
ListBoxItem itemToRemove = sender as ListBoxItem;
FadeOut(itemToRemove); // this needs to wait until animation is completed
ListBox.Items.Remove(item); // because this line will remove it immediately
这是我的故事板:
<Storyboard x:Key="fadeOut">
<ObjectAnimationUsingKeyFrames BeginTime="0:0:0" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation BeginTime="0:0:0.0" Duration="0:0:0.5" From="1" Storyboard.TargetProperty="Opacity" To="0" />
</Storyboard>
我这样称呼它:
((Storyboard)FindResource("fadeOut")).Begin(item);
但是,我想等到故事板完成后再继续。
我试过了:
((Storyboard)FindResource("fadeOut")).Completed += FadeOut_Completed;
((Storyboard)FindResource("fadeOut")).Begin(item);
但是,我无法将参数 item 传递给 FadeOut_Completed 以将其从 ListBox 中删除。
所以我尝试了这个:
FadeOut(item).Wait();
在哪里
public Task FadeOut(ListBoxItem item)
{
var tcs = new TaskCompletionSource<bool>();
((Storyboard)FindResource("fadeOut")).Begin(item);
((Storyboard)FindResource("fadeOut")).Completed += (s, e) => tcs.SetResult(true);
return tcs.Task;
}
但这被卡住了。我是线程和异步的新手。有人可以指出我哪里出错或提出替代方案吗?
【问题讨论】:
-
由于您从
FadeOut返回Task,您可以.ContinueWith删除代码... -
@Don't
Wait()一个任务。它将阻塞调用线程。请改用await FadeOut(item).。 -
@EZI 这告诉我它不能,除非它是异步的。然后当我将其标记为异步时,它会告诉我返回类型在我的返回语句中是无效的。
-
@crclayton 然后用
Task替换void -
淡出功能是Task。如果你的意思是里面有这些调用的函数,我不能。那将意味着改变太多。
标签: c# wpf multithreading xaml asynchronous