C# 从WPF/MVVM中的ViewModel启动动画

C# 从WPF/MVVM中的ViewModel启动动画,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在编写一个MVVM应用程序,并开始添加一些动画。我想在ViewModel上调用一些东西,它启动了故事板,但它实际上不起作用。由于某种原因,IDChanged处理程序从不激发 我还发现可以在EventTriggers上启动动画,但我不知道如何在ViewModel上启动动画。我的VM中有一个反映应用程序状态的属性。视图中已设置动画的元素有一个数据触发器,当VM属性具有某个值时,该触发器将启动情节提要。我最终向ViewModel添加了一个AnimationStarted事件,其中包含动画的关键字符

我正在编写一个MVVM应用程序,并开始添加一些动画。我想在ViewModel上调用一些东西,它启动了故事板,但它实际上不起作用。由于某种原因,IDChanged处理程序从不激发


我还发现可以在EventTriggers上启动动画,但我不知道如何在ViewModel上启动动画。

我的VM中有一个反映应用程序状态的属性。视图中已设置动画的元素有一个数据触发器,当VM属性具有某个值时,该触发器将启动情节提要。

我最终向ViewModel添加了一个AnimationStarted事件,其中包含动画的关键字符串。然后在视图上,我以编程方式创建动画,订阅AnimationStarted事件,并在其触发时启动相应的动画。

我通过使用DataTrigger并将其绑定到ViewModel中的属性来完成此操作。当“FlashingBackGround”属性设置为“ON”时,故事板动画开始

还要确保在项目中包含对“Microsoft.Expression.Interactions”的引用

XAML:(这直接进入根节点)


最后,Viewmodel必须继承“INotifyPropertyChanged”

我遇到了同样的问题,这些帖子都没有真正的帮助,因为动画是在代码中的,其中一些是大而复杂的,需要波动的变量,所以它们必须留在代码中。我通过在触发动画的用户控件(视图)中添加依赖项属性,并将它们绑定到视图模型中的属性来解决这个问题。不知道(/关心)这是否违反了某些东西,因为它工作得非常好!干杯,stepp

摘录:

(视图)用户控制代码隐藏:

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        SetAnimationBindings();
    }

    private void SetAnimationBindings()
    {
        _dialogStartPosition = mbFolderBrowse.Margin;

        var propName = "StartDialogAnimation";
        var binding = new Binding(propName) { Mode = BindingMode.TwoWay };
        this.SetBinding(DialogAnimationProperty, binding);

        propName = "StartProgressAnimation";
        binding = new Binding(propName) { Mode = BindingMode.TwoWay };
        this.SetBinding(ProgressAnimationProperty, binding);
    }

    #region Animation Properties
    #region DialogAnimation
    public static readonly DependencyProperty DialogAnimationProperty = 
        DependencyProperty.Register("DialogAnimation", typeof(bool),
            typeof(Manage), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDialogAnimationChanged));
    public bool DialogAnimation
    {

        get { return (bool)this.GetValue(DialogAnimationProperty); }
        set
        {
            var oldValue = (bool)this.GetValue(DialogAnimationProperty);
            if (oldValue != value) this.SetValue(DialogAnimationProperty, value);
        }
    }

    private static void OnDialogAnimationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        Manage m = o as Manage;

        if ((bool)e.NewValue == true)
            m.SlideInDialogPanel(); // animations
        else
            m.SlideOutDialogPanel();
    }
    #endregion
视图模型:

public bool StartDialogAnimation
{
    get { return _startDialogAnimation; }
    set
    {
        if (_startDialogAnimation != value)
        {
            _startDialogAnimation = value;
            RaisePropertyChanged("StartDialogAnimation");
        }
    }
}

我知道怎么做。您设置了一个触发器,以便在输入条件时启动情节提要。但我只需要做一个一次性的动画:我想在UI元素上做一个快速、临时的flash来引起人们的注意。我还没有考虑推广这个,所以我不知道这是否对你有帮助。我曾经有过类似的需求。如果有一分钟没有活动,我必须“闪动”一个按钮。我通过在按钮上附加一个故事板来实现这一点,故事板在一分钟内什么也不做,然后进行flash。在我的例子中,当点击按钮时,按钮就消失了,这样场景就更简单了。在UI元素上闪现以吸引注意力听起来像是只与视图相关。是否有一种方式可以让视图自行决定何时启动闪光灯?为什么VM会关心刷新UI元素?很抱歉,这可能没有多大帮助。在一个窗口上触发的多个命令会在另一个窗口中触发此闪光灯。我的窗口模型是这样设置的:VM知道窗口之间的关系,但视图不知道。您有关于此DataTrigger的一些示例代码吗?我试过了,但对我的朋友来说并没有真正起作用DataBindings@Tigraine-我有一个使用模型项的文本值的示例。有趣的方法。但是为什么不直接使用
布尔值而不是“开”/“关”字符串呢?请确保也添加“System.Windows.Interactivity.dll”。
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        SetAnimationBindings();
    }

    private void SetAnimationBindings()
    {
        _dialogStartPosition = mbFolderBrowse.Margin;

        var propName = "StartDialogAnimation";
        var binding = new Binding(propName) { Mode = BindingMode.TwoWay };
        this.SetBinding(DialogAnimationProperty, binding);

        propName = "StartProgressAnimation";
        binding = new Binding(propName) { Mode = BindingMode.TwoWay };
        this.SetBinding(ProgressAnimationProperty, binding);
    }

    #region Animation Properties
    #region DialogAnimation
    public static readonly DependencyProperty DialogAnimationProperty = 
        DependencyProperty.Register("DialogAnimation", typeof(bool),
            typeof(Manage), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDialogAnimationChanged));
    public bool DialogAnimation
    {

        get { return (bool)this.GetValue(DialogAnimationProperty); }
        set
        {
            var oldValue = (bool)this.GetValue(DialogAnimationProperty);
            if (oldValue != value) this.SetValue(DialogAnimationProperty, value);
        }
    }

    private static void OnDialogAnimationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        Manage m = o as Manage;

        if ((bool)e.NewValue == true)
            m.SlideInDialogPanel(); // animations
        else
            m.SlideOutDialogPanel();
    }
    #endregion
public bool StartDialogAnimation
{
    get { return _startDialogAnimation; }
    set
    {
        if (_startDialogAnimation != value)
        {
            _startDialogAnimation = value;
            RaisePropertyChanged("StartDialogAnimation");
        }
    }
}