如何创建自定义DataGrid

时间:2013-08-11 16:39:39

标签: c# wpf mvvm user-controls wpfdatagrid

所有,在前一个问题的答案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>

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

  

使用您需要内置的功能创建派生DataGridTextColumn可能是更好的选择,因为如果您使用虚拟化,使用TargetUpdated几乎是不可能的。但如果您制作了自定义DataGridTextColumn,那么您应该可以使其正常运行。

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

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

感谢您的时间。

1 个答案:

答案 0 :(得分: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); } } } 事件来使其工作。

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

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

的TextBlock:

<DataTemplate x:Key="readOnlyCellUpdatedStyle">
    <local:VirtualizingNotifyTextBlock Text="{Binding KeyIndex, NotifyOnTargetUpdated=True}" NotifyColor="Blue" NotifyDuration="250" NotifyRepeat="4" />
</DataTemplate>

的Xaml:

{{1}}