DataTrigger не срабатывает, когда значение свойства изменяется несколько раз в коротком окне

Я обнаружил интересную проблему в своем приложении WPF, связанную с тем, что MultiDataTrigger не запускает StoryBoard для анимации ячейки сетки данных. У меня есть элемент управления сеткой данных WPF, который привязан к ObservableCollection, содержащему POCO, которые реализуют INotifyPropertyChanged.

Чего я хочу достичь

Сетка данных в реальном времени, которая мигает обновлениями при изменении значений. Когда значение увеличивается, я хочу, чтобы ячейка мигала зеленым; когда значение уменьшается, я хочу, чтобы ячейка мигала красным. Анимация просто анимирует цвет фона ячейки от сплошного до прозрачного с интервалом в 1 секунду.

Проблема

Раскадровка не запускается MultiDataTrigger после первого раза. MultiDataTrigger отслеживает изменения двух свойств: IsPositive и HasValueChanged. Первоначально HasValueChanged имеет значение false, а затем изменяется с false на true, как только свойство Value установлено, и анимация работает в первый раз. После этого HasValueChanged изменяется с false на true, чтобы вызвать уведомление об изменении, но анимация не запускается.

Вот стиль XAML, который я применяю к каждой ячейке сетки данных:


Вот XAML для анимации:


    



    

] Вот код для объекта POCO, привязанного к каждой ячейке:

using System;
using System.Threading;
using Microsoft.Practices.Prism.ViewModel;

namespace RealTimeDataGrid
{
    public class Cell : NotificationObject
    {
        public Cell(int ordinal, int value)
        {
            Ordinal = ordinal;
            _value = value;
            LastUpdated = DateTime.MaxValue;
        }

        public void SetValue(int value)
        {
            Value = value;

            // Pulse value changed to get WPF to fire DataTriggers
            HasValueChanged = false;
            Thread.Sleep(100);
            HasValueChanged = true;
        }

        private int _value;

        public int Value
        {
            get { return _value; }
            private set
            {
                if (_value == value)
                    return;

                _value = value;

                // Performance optimization, using lambdas here causes performance issues
                RaisePropertyChanged("IsPositive");
                RaisePropertyChanged("Value");
            }
        }

        private bool _hasValueChanged;

        public bool HasValueChanged
        {
            get { return _hasValueChanged; }
            set
            {
                if (_hasValueChanged == value)
                    return;

                _hasValueChanged = value;

                // Performance optimization, using lambdas here causes performance issues
                RaisePropertyChanged("HasValueChanged");
            }
        }

        public int Ordinal { get; set; }

        public DateTime LastUpdated { get; set; }

        public bool IsPositive
        {
            get { return Value >= 0; }
        }

        public TimeSpan TimeSinceLastUpdate
        {
            get { return DateTime.Now.Subtract(LastUpdated); }
        }
    }
}

Очевидное исправление

Добавление Thread.Sleep (100) между установкой HasValueChanged дважды в методе SetValue, похоже, решает проблему с не срабатыванием MultiDataTrigger, но имеет нежелательные побочные эффекты.

Видео о проблеме

Нажмите здесь , чтобы просмотреть видео с неработающей версией.

Нажмите здесь , чтобы просмотреть видео с фиксированная версия.

«Фиксированная» версия не идеальна, потому что Thread.Sleep заставляет ячейки обновляться явно последовательно, а не одновременно, как в сломанной версии. Кроме того, наличие Thread.Sleep заставляет меня чувствовать себя плохо :)

Прежде всего; Я все неправильно делаю? Есть ли более простой / лучший способ достичь того, чего я хочу? Если не,Каково решение этой проблемы, не прибегая к добавлению Thread.Sleep (запах кода!)?

Почему WPF не вызывает срабатывание DataTrigger при быстром изменении значений? Есть ли что-то, что заставляет WPF «пропускать» изменения свойств; или WPF просто игнорирует изменения, которые переходят от одного значения к другому, а затем возвращаются к исходному значению в течение определенного периода времени?

Спасибо за любую помощь!

6
задан H.B. 4 November 2011 в 16:28
поделиться