【问题标题】:WPF Datagrid - Highlight row on data changeWPF Datagrid - 突出显示数据更改行
【发布时间】:2019-09-22 13:58:02
【问题描述】:

我有这个工作存根:

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

视图模型

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

项目视图模型

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 中第二项的数据更新。

问题

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

【问题讨论】:

    标签: c# .net wpf xaml events


    【解决方案1】:

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

    公共静态类动画师 { 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>
    

    【讨论】:

      【解决方案2】:

      您需要执行以下操作:

      • DataGrid.RowStyle 设置为新的Style - 可能会覆盖默认的ControlTemplate(请参阅this answer)以添加可以“突出显示”的背景元素
      • Style.Triggers 中定义一个适当的Trigger - 可能是基于TheData 不为空的DataTrigger
      • 使用触发器启动动画 - 见msdn documentation

      您可能需要做一些事情来推迟此样式的应用 - 大概您不希望所有行在初始加载时都突出显示。为此,您可以考虑在Loaded 触发后使用Xaml behavior 来设置RowStyle

      【讨论】:

        猜你喜欢
        • 2011-10-01
        • 2023-03-29
        • 2013-06-11
        • 2011-05-27
        • 2023-03-19
        • 2011-06-24
        • 2015-10-31
        • 2012-06-06
        • 1970-01-01
        相关资源
        最近更新 更多