高亮显示数据更改行

高亮显示数据更改行

本文介绍了WPF Datagrid-高亮显示数据更改行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个工作存根:

XAML

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False" CanUserAddRows="False" GridLinesVisibility="None" HeadersVisibility="None" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Visible">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label>
                            <TextBlock Text="{Binding Id}" />
                        </Label>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label>
                            <TextBlock Text="{Binding TheData}" />
                        </Label>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>

隐藏代码

using System.Windows;
using WpfApp1.ViewModels;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            DataContext = new MainWindowVM();
            InitializeComponent();
        }
    }
}

ViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WpfApp1.ViewModels
{
    public class MainWindowVM
    {
        Random random = new Random();
        public List<ListItemVM> MyList { get; set; } = new List<ListItemVM>
        {
            new ListItemVM(1, "Data1"),
            new ListItemVM(2, "Data2"),
            new ListItemVM(3, "Data3"),
        };

        public MainWindowVM()
        {
            // Start an infinite task that updates the data every 2 second
            // This emulates an external process that sends new data that must be displayed
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Task.Delay(2000).Wait();
                    var nextData = new string(Enumerable.Repeat("ABCDEFG", 10).Select(s => s[random.Next(s.Length)]).ToArray());
                    MyList[1].SetNewData(nextData);
                }
            });
        }
    }
}

项目ViewModel

using System.ComponentModel;

namespace WpfApp1.ViewModels
{
    public class ListItemVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public int Id { get; set; }
        public string TheData { get; set; }

        public ListItemVM(int id, string theData)
        {
            Id = id;
            TheData = theData;
        }

        internal void SetNewData(string nextData)
        {
            // Change data
            TheData = nextData;
            // Notify the UI of the change
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TheData)));
        }
    }
}

每2秒,我会在UI中看到DataGrid中第二项的数据更新.

Every 2 seconds, I see the data update in the UI for the second item in the DataGrid.

问题

我希望DataGridRow在每次更新时都在1秒内突出显示并淡出.有人可以帮我实现这一目标吗?

I would like the DataGridRow to get highlighted and fade out in 1 second on every update. Can someone help me achieve that please?

推荐答案

您可以创建执行动画的附加行为:

You could create an attached behaviour that performs the animation:

公共静态类Animator { 私有静态只读HashSet _rows = new HashSet();

public static class Animator { private static readonly HashSet _rows = new HashSet();

    public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached("Value", typeof(object),
        typeof(Animator), new PropertyMetadata(new PropertyChangedCallback(OnValuePropertyChanged)));

    public static object GetValue(DataGridRow d) => d.GetValue(ValueProperty);

    public static void SetValue(DataGridRow d, object value) => d.SetValue(ValueProperty, value);

    private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DataGridRow row = (DataGridRow)d;
        if (!_rows.Contains(row))
        {
            _rows.Add(row);
            row.Unloaded += Row_Unloaded;
        }
        else
        {
            ColorAnimation animation = new ColorAnimation();
            animation.From = Colors.Gray;
            animation.To = Colors.White;
            animation.Duration = new Duration(TimeSpan.FromSeconds(1));
            Storyboard.SetTarget(animation, row);
            Storyboard.SetTargetProperty(animation, new PropertyPath("Background.Color"));
            Storyboard sb = new Storyboard();
            sb.Children.Add(animation);
            sb.Begin();
        }
    }

    private static void Row_Unloaded(object sender, RoutedEventArgs e)
    {
        DataGridRow row = (DataGridRow)sender;
        _rows.Remove(row);
        row.Unloaded -= Row_Unloaded;
    }
}

用法:

<DataGrid.ItemContainerStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="local:Animator.Value" Value="{Binding TheData}" />
    </Style>
</DataGrid.ItemContainerStyle>

这篇关于WPF Datagrid-高亮显示数据更改行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 04:53