All, in this answer https://stackoverflow.com/a/18136371/626442 to a previous question, the answer provided a solution to the problem of my animation not firing. The code was
<DataTemplate x:Key="readOnlyCellUpdatedStyle">
<TextBlock Text="{Binding KeyIndex, Mode=TwoWay,NotifyOnTargetUpdated=True}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="White"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color"
Duration="0:0:0.3"
From="White"
To="Red"
RepeatBehavior="3x"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
This fires the animation when I update the KeyIndex
column via the ViewModel. However, I only want the animation of the cells of the DataGridTextColumn
to animate when the values are updated but they also fire when the DataGrid
is scrolled. I was suggested
It may be a better option to create a derived
DataGridTextColumn
with the features you need built in, as usingTargetUpdated
will be pretty much impossible if you are using Virtualization. But if you made a customDataGridTextColumn
you should be able to get it working.
How do I create a custom/derived `DataGridTextColumn (I have access to blend too)?
I have no idea how to do this and the documentation on this particular concept is sparse.
Thanks for your time.
It turned out to be quite difficult to get this working with Virtualization
when using VirtualizationMode="Recycling"
I found a way to get it working by deriving TextBlock
and attaching to the PropertyChanged
event of the bound object.
When the value changes the animation is played, but if you scroll the recycled item does not continue to play the animation.
This is a pretty rough example but I am sure you can clean up and modify to your needs.
TextBlock:
public class VirtualizingNotifyTextBlock : TextBlock
{
private INotifyPropertyChanged _dataItem;
private string _propertyName;
public VirtualizingNotifyTextBlock()
: base()
{
this.TargetUpdated += NotifyTextBlock_TargetUpdated;
}
public static readonly RoutedEvent PropertyChangedEvent = EventManager.RegisterRoutedEvent("PropertyChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(VirtualizingNotifyTextBlock));
public static readonly DependencyProperty NotifyDurationProperty = DependencyProperty.Register("NotifyDuration", typeof(int), typeof(VirtualizingNotifyTextBlock), new PropertyMetadata(300));
public static readonly DependencyProperty NotifyRepeatProperty = DependencyProperty.Register("NotifyRepeat", typeof(int), typeof(VirtualizingNotifyTextBlock), new PropertyMetadata(3));
public static readonly DependencyProperty NotifyColorProperty = DependencyProperty.Register("NotifyColor", typeof(Color), typeof(VirtualizingNotifyTextBlock), new PropertyMetadata(Colors.Red));
public Color NotifyColor
{
get { return (Color)GetValue(NotifyColorProperty); }
set { SetValue(NotifyColorProperty, value); }
}
public int NotifyDuration
{
get { return (int)GetValue(NotifyDurationProperty); }
set { SetValue(NotifyDurationProperty, value); }
}
public int NotifyRepeat
{
get { return (int)GetValue(NotifyRepeatProperty); }
set { SetValue(NotifyRepeatProperty, value); }
}
public INotifyPropertyChanged DataItem
{
get { return _dataItem; }
set
{
if (_dataItem != null)
{
Background = new SolidColorBrush(Colors.Transparent);
_dataItem.PropertyChanged -= DataItem_PropertyChanged;
}
_dataItem = value;
if (_dataItem != null)
{
_dataItem.PropertyChanged += DataItem_PropertyChanged;
}
}
}
private void NotifyTextBlock_TargetUpdated(object sender, DataTransferEventArgs e)
{
var binding = this.GetBindingExpression(VirtualizingNotifyTextBlock.TextProperty);
if (binding != null)
{
_propertyName = binding.ResolvedSourcePropertyName;
DataItem = binding.DataItem as INotifyPropertyChanged;
}
}
private void DataItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == _propertyName)
{
var animation = new ColorAnimation(NotifyColor, new Duration(TimeSpan.FromMilliseconds(NotifyDuration)));
animation.RepeatBehavior = new RepeatBehavior(NotifyRepeat);
animation.AutoReverse = true;
Background = new SolidColorBrush(Colors.Transparent);
Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
}
}
}
Xaml:
<DataTemplate x:Key="readOnlyCellUpdatedStyle">
<local:VirtualizingNotifyTextBlock Text="{Binding KeyIndex, NotifyOnTargetUpdated=True}" NotifyColor="Blue" NotifyDuration="250" NotifyRepeat="4" />
</DataTemplate>