属性值在短窗口内多次更改时,不会触发DataTrigger

如何解决属性值在短窗口内多次更改时,不会触发DataTrigger

| 我在WPF应用程序中发现了一个有趣的问题,该问题与multidatatrigger没有启动StoryBoard来为数据网格单元设置动画有关。我有一个WPF数据网格控件,该控件绑定到包含实现INotifyPropertyChanged的POCO的ObservableCollection。 我想要实现的目标 实时数据网格,随着值的变化闪烁更新。当该值增加时,我希望该单元格闪烁绿色;当值减小时,我希望单元格闪烁红色。动画仅在1秒的时间间隔内将单元格的背景颜色从纯色变为透明。 问题 第一次后,multidatatrigger不会启动情节提要。 multidatatrigger正在监视对两个属性的更改:IsPositive和HasValueChanged。最初,HasValueChanged为false,然后在设置Value属性后立即从false更改为true,并且动画第一次生效。此后,HasValueChanged从false变为true,以触发更改通知,但动画未开始。 这是我应用于每个数据网格单元的XAML样式:
<Style targettype=\"{x:Type TextBlock}\">
    <Style.Setters>
        <Setter Property=\"Background\"
                Value=\"Aqua\" />
    </Style.Setters>
    <Style.Triggers>
        <multidatatrigger>
            <multidatatrigger.Conditions>
                <Condition Binding=\"{Binding Path=HasValueChanged}\"
                            Value=\"True\" />
                <Condition Binding=\"{Binding Path=IsPositive}\"
                            Value=\"True\" />
            </multidatatrigger.Conditions>
            <multidatatrigger.Enteractions>
                <RemoveStoryboard BeginStoryboardName=\"PositiveValueCellStoryboard\" />
                <RemoveStoryboard BeginStoryboardName=\"NegativeValueCellStoryboard\" />
                <BeginStoryboard Name=\"PositiveValueCellStoryboard\"
                                    Storyboard=\"{StaticResource PositiveValueCellAnimation}\"
                                    HandoffBehavior=\"SnapShotAndReplace\" />
            </multidatatrigger.Enteractions>
        </multidatatrigger>
        <multidatatrigger>
            <multidatatrigger.Conditions>
                <Condition Binding=\"{Binding Path=HasValueChanged}\"
                            Value=\"True\" />
                <Condition Binding=\"{Binding Path=IsPositive}\"
                            Value=\"False\" />
            </multidatatrigger.Conditions>
            <multidatatrigger.Enteractions>
                <RemoveStoryboard BeginStoryboardName=\"PositiveValueCellStoryboard\" />
                <RemoveStoryboard BeginStoryboardName=\"NegativeValueCellStoryboard\" />
                <BeginStoryboard Name=\"NegativeValueCellStoryboard\"
                                    Storyboard=\"{StaticResource NegativeValueCellAnimation}\"
                                    HandoffBehavior=\"SnapShotAndReplace\" />
            </multidatatrigger.Enteractions>
        </multidatatrigger>
    </Style.Triggers>
</Style>
这是动画的XAML:
<Storyboard x:Key=\"NegativeValueCellAnimation\">
    <ColorAnimation Storyboard.TargetProperty=\"Background.(SolidColorBrush.Color)\"
                    Timeline.DesiredFrameRate=\"10\"
                    RepeatBehavior=\"1x\"
                    From=\"Red\"
                    To=\"Transparent\"
                    Duration=\"0:0:1\" />
</Storyboard>

<Storyboard x:Key=\"PositiveValueCellAnimation\">
    <ColorAnimation Storyboard.TargetProperty=\"Background.(SolidColorBrush.Color)\"
                    Timeline.DesiredFrameRate=\"10\"
                    RepeatBehavior=\"1x\"
                    From=\"Green\"
                    To=\"Transparent\"
                    Duration=\"0:0:1\" />
</Storyboard>
这是绑定到每个单元格的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); }
        }
    }
}
表观修复 在SetValue方法的两次设置HasValueChanged之间添加Thread.Sleep(100)似乎可以解决multidatatrigger不触发但具有不良副作用的问题。 问题的视频 单击此处查看损坏版本的视频。 单击此处观看固定版本的视频。 \'fixed \'版本不是理想的,因为Thread.Sleep导致单元以明显的顺序方式更新,而不是像损坏版本中那样同时更新。此外,在其中拥有Thread.Sleep会让我感觉很不好:) 首先;我要解决所有这些错误吗?有没有更简单/更好的方法来实现我想要的?如果不是,那么无需添加Thread.Sleep(代码气味!),该问题的解决方案是什么? 当值快速更改时,WPF为什么不触发DataTrigger?是否有某些因素导致WPF的'miss \'属性更改;还是WPF只是忽略在某个时间范围内从一个值到另一个值然后又回到原始值的更改? 谢谢你的帮助!     

解决方法

        对我来说,使用像事件这样的属性似乎比ѭ3更糟,我建议结合使用两个RoutedEvents(以区分
Changed+Positive
Changed+Negative
)和EventTriggers。 如果您想坚持使用
Thread.Sleep
,则可能应该在后台执行:
// IDE-free code,may be broken
HasValueChanged = false;
new Thread((ThreadStart)(() =>
{
    Thread.Sleep(100);
    HasValueChanged = true;
})).Start();
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?