【问题标题】:Using ObservableCollection firing Binding.TargetUpdated only on single item仅在单个项目上使用 ObservableCollection 触发 Binding.TargetUpdated
【发布时间】:2014-06-21 17:02:27
【问题描述】:

我有三个文本块,其 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

如何将动画限制为仅显示绑定值已更新的文本块?

【问题讨论】:

  • 发布相关的 XAML 和代码(如果有)

标签: wpf data-binding observablecollection


【解决方案1】:

当您使用绑定到集合的 indexer 属性的索引时,UI 不知道哪个索引已更改,它只是通知 indexer 属性已更改而没有指定哪个索引,因此,在您的情况下,它会刷新所有 3 @ 987654322@ 提高 TargetUpdated 事件。发生的事情是ObservableCollection 引发PropertyChanged 事件,Binding.IndexerName 作为属性名称。要解决您的问题而不是使用 3 TextBlocks,您可以使用 ItemsControl

<ItemsControl ItemsSource="{Binding CurrentAnswers}">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <TextBlock Style="{StaticResource FadeInTextBlock}" Text="{Binding NotifyOnTargetUpdated=True}" />
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

这将重复 TextBlock 的次数与您在 CurrentAnswers 中的项目数一样多

【讨论】:

  • 但这并不能解决每个TextBlock每次都刷新的问题,对吧?除了绑定到单独的属性之外,有没有办法只让更新的TextBlock 触发动画?在我的情况下,TextBlocks 的数量是固定的。
  • 它应该可以解决您的问题。我已经测试过它并且它有效,我也在其他地方使用过它。此解决方案不涉及 indexer 属性,因此它不会从它获取刷新通知,而是从INotifyCollectionChanged 接口获取通知,该接口明确说明哪些项目已更改,因此这只会导致更改的项目刷新并触发动画
  • 感谢您的解决方案!一切似乎都如我所愿。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 2020-04-11
  • 1970-01-01
相关资源
最近更新 更多