INotifyPropertyChanged 和更改数据的动画

INotifyPropertyChanged and animation of changing data

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

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

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

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

您可以创建附加的 属性 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}" />