我有三个textblock与Text
属性绑定到ObservableCollection
的项目:
<TextBlock Style="{StaticResource FadeInTextBlock}" Text="{Binding Path=CurrentAnswers[0], NotifyOnTargetUpdated=True}" />
<TextBlock Style="{StaticResource FadeInTextBlock}" Text="{Binding Path=CurrentAnswers[1], NotifyOnTargetUpdated=True}" />
<TextBlock Style="{StaticResource FadeInTextBlock}" Text="{Binding Path=CurrentAnswers[2], NotifyOnTargetUpdated=True}" />
INotifyPropertyChanged
实现后的属性:
public ObservableCollection<Answer> CurrentAnswers
{
get { return currentAnswers; }
set { currentAnswers = value; RaisePropertyChanged("CurrentAnswers"); }
}
每个文本块使用相同的样式,包含Binding.TargetUpdated
事件触发器,在实际文本中淡出:
<Style x:Key="FadeInTextBlockTwo" TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:0" To="0.0"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1" From="0.0" To="1.0" BeginTime="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
当我在ObservableCollection
中改变一个项目时,所有的文本块都在触发事件,并做淡入:
CurrentAnswer[1] = "New Text";
// Textblock 1 - 3 do the fade in animation,
// even if only Textblock 2 has been updated
如何将动画限制为只有绑定值已更新的Textblock ?
当你使用索引时,你绑定到你的集合的indexer属性,UI不知道哪个索引已经改变,它只是通知indexer属性已经改变,而不指定哪个索引,所以,在你的情况下,它刷新所有3个TextBlocks
引发TargetUpdated
事件。发生的是ObservableCollection
引发PropertyChanged
事件,并将Binding.IndexerName
作为属性名。为了解决您的问题,您可以使用ItemsControl
TextBlocks
。<ItemsControl ItemsSource="{Binding CurrentAnswers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource FadeInTextBlock}" Text="{Binding NotifyOnTargetUpdated=True}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这将重复TextBlock
的次数和CurrentAnswers
的次数一样多