2

所有,在这个回答https://stackoverflow.com/a/18136371/626442对上一个问题的回答中,回答为我的动画不触发的问题提供了一个解决方案。代码是

<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>

KeyIndex当我通过 ViewModel更新列时,这会触发动画。但是,我只希望在更新值时动画单元格的动画,但在滚动DataGridTextColumn时它们也会触发。DataGrid有人建议我

DataGridTextColumn使用您需要的内置功能创建派生可能是一个更好的选择,因为TargetUpdated如果您使用虚拟化,使用将几乎是不可能的。但是,如果您进行了自定义DataGridTextColumn,则应该能够使其正常工作。

如何创建自定义/派生的`DataGridTextColumn(我也可以访问混合)?

我不知道如何做到这一点,而且关于这个特定概念的文档很少。

谢谢你的时间。

4

1 回答 1

3

事实证明,在使用时很难Virtualization使用它VirtualizationMode="Recycling"

我找到了一种通过派生TextBlock并附加到PropertyChanged绑定对象的事件来使其工作的方法。

当值改变时播放动画,但如果滚动回收的项目不会继续播放动画。

这是一个非常粗略的示例,但我相信您可以根据需要进行清理和修改。

文本块:

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);
        }
    }

}

xml:

<DataTemplate x:Key="readOnlyCellUpdatedStyle">
    <local:VirtualizingNotifyTextBlock Text="{Binding KeyIndex, NotifyOnTargetUpdated=True}" NotifyColor="Blue" NotifyDuration="250" NotifyRepeat="4" />
</DataTemplate>
于 2013-08-12T02:50:24.517 回答