【问题标题】:INotifyPropertyChanged and animation of changing dataINotifyPropertyChanged 和更改数据的动画
【发布时间】:2017-05-28 20:51:38
【问题描述】:

在我的应用程序中,我有一个矩形指示基于其宽度的信息,这只是一个自定义进度条。我没有将其宽度绑定到 ViewModels 属性,因为更改并不平滑,并且条形图看起来不连贯,但我希望在数据更改时获得平滑的动画。

因此,我的事件处理程序对 PropertyChanged 事件的底层依赖作出反应,通知应反映在 UI 中的相应属性,但矩形的处理方式不同。基本上它运行

Rectangle.BeginAnimation(FrameworkElement.WidthProperty,
    new DoubleAnimation(width, TimeSpan.FromMilliseconds(200)));

我很好奇引入一个宽度属性是否合理,当它发生变化时会引发PropertyChanged 事件,然后对该属性进行动画处理,以便通过在我的 ViewModel 中为宽度属性设置动画来动画矩形。在那种情况下甚至可以为自定义属性设置动画吗?

【问题讨论】:

    标签: c# wpf animation binding inotifypropertychanged


    【解决方案1】:

    您可以创建一个附加属性 TargetWidth,在设置时为 FrameworkElement 的 Width 属性设置动画。

    public static class FrameworkElementExtension
    {
        public static readonly DependencyProperty TargetWidthProperty =
            DependencyProperty.RegisterAttached(
                "TargetWidth",
                typeof(double),
                typeof(FrameworkElementExtension),
                new PropertyMetadata(TargetWidthPropertyChanged));
    
        public static double GetTargetWidth(this FrameworkElement obj)
        {
            return (double)obj.GetValue(TargetWidthProperty);
        }
    
        public static void SetTargetWidth(this FrameworkElement obj, double value)
        {
            obj.SetValue(TargetWidthProperty, value);
        }
    
        private static void TargetWidthPropertyChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var element = obj as FrameworkElement;
            if (element != null)
            {
                if (double.IsNaN(element.Width))
                {
                    element.Width = 0;
                }
    
                element.BeginAnimation(
                    FrameworkElement.WidthProperty,
                    new DoubleAnimation((double)e.NewValue, TimeSpan.FromSeconds(0.2)));
            }
        }
    }
    

    您现在可以直接设置TargetWidth 喜欢

    Rectangle.SetTargetWidth(width);
    

    或将其绑定到视图模型属性:

    <Rectangle ... local:FrameworkElementExtension.TargetWidth="{Binding RectangleWidth}" />
    

    【讨论】:

    • 尽管我在 Rectangle 上添加了 Width 的默认值,但出现了 NaN。因此,我必须通过使用element.ActualWidth 引用它来将fromValue 添加到DoubleAnimation,然后您的解决方案才有效。关于动画的一个简单问题:假设我在最后一个动画尚未完成时获得了值的更新,第二个调用的动画会在第一个动画之后执行还是立即开始,以至于没有注意到延迟?跨度>
    • 它将立即从当前值开始。因此我不建议设置动画的 From 值。最好确保 Width 最初不是 NaN。
    • 没关系,发生了一些奇怪的事情 - 在 XAML 中为 Rectangle 手动设置默认的 Width 之前没有帮助,但它现在可以防止 NaN。它现在按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2012-10-27
    • 2016-08-09
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    相关资源
    最近更新 更多