How to datatrigger an animation upon updated ViewModel property?
Asked Answered
B

1

5

I have the following DataGrid cell, which I would like to animate its background colour briefly as soon as the underlying LastTradePrice property changes its value.

<DataGridTextColumn Header="Last Trade Price" Binding="{Binding LastTradePrice}">
     <DataGridTextColumn.CellStyle>
          <Style TargetType="DataGridCell">
             <Style.Triggers>
                // ???
                <DataTrigger Binding="{Binding LastTradePrice}" Value="True"> 
                     <DataTrigger.EnterActions>
                          <BeginStoryboard>
                              <Storyboard>
                                 <ColorAnimation To="Aqua" Duration="0:0:0.3" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"/>
                              </Storyboard>
                          </BeginStoryboard>
                      </DataTrigger.EnterActions>
                 </DataTrigger>
             </Style.Triggers>
          </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

1) The line <DataTrigger Binding="{Binding LastTradePrice}" Value="True"> makes no sense though.

The property LastTradePrice is obviously not a boolean to be measured with value = True. How can I make the trigger to fire whenever the property is updated? Obviously I have INotification implemented:

        public double LastTradePrice
        {
            get { return _model.LastTradePrice; }
            set
            {
                if (value != _model.LastTradePrice)
                {
                    LastTradePrice = value;
                    OnPropertyChanged("LastTradePrice");
                }
            }
        }

2) If I would have stored the whole style definition inside <Window.Resources>, how would I have accessed the ViewModels property LastTradePrice?

Many Thanks

Bursar answered 23/2, 2014 at 16:30 Comment(3)
Check this link. Idea is that it will trigger animation on Binding.TargetUpdated event. I've tested it and it works but it also triggers animation for initial value binding.Delectation
I like this solution. It utilises EventTrigger and no code change in ViewModel is required. If you like you could extend this as an answer or I can do it too. :)Bursar
Sure. I can put my example into an answer.Delectation
D
10

As mentioned in the comment you can utilize Binding.TargetUpdated event.

Occurs when a value is transferred from the binding source to the binding target, but only for bindings with the NotifyOnTargetUpdated value set to true.

Which means that if value is pulled from view model into view, and NotifyOnTargetUpdated == True against binding, TargetUpdated event is raised. So it will be raised when value is initially displayed or later when you raise INotifyPropertyChanged.PropertyChanged event in your view model.

<DataGridTextColumn Header="Last Trade Price" Binding="{Binding Path=LastTradePrice, NotifyOnTargetUpdated=True}">
   <DataGridTextColumn.CellStyle>
      <Style TargetType="DataGridCell">
         <Style.Triggers>
            <EventTrigger RoutedEvent="Binding.TargetUpdated">
               <BeginStoryboard>
                  <Storyboard>
                     <ColorAnimation To="Aqua" Duration="0:0:0.3" AutoReverse="True" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" />
                  </Storyboard>
               </BeginStoryboard>
            </EventTrigger>
         </Style.Triggers>
      </Style>
   </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

Also if want to briefly notify with colour change you want to set AutoReverse="True" against ColorAnimation otherwise Aqua colour will stay. The only downside of this solution is that it will trigger also when DataGrid is created and initial values are loaded.

There is also Binding.SourceUpdated event which works with NotifyOnSourceUpdated against binding and works in the opposite direction to TargetUpdated event. It will be triggered when new value is transmitted from view to view model.

Gets or sets a value that indicates whether to raise the SourceUpdated event when a value is transferred from the binding target to the binding source.

By default both NotifyOnTargetUpdated abd NotifyOnSourceUpdated will be set to false to save on raising 2 additional event when values are transmitted between view and view model.

Delectation answered 24/2, 2014 at 10:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.