2010-03-28 3 views
7

Я пишу приложение MVVM и начал вставлять несколько анимаций. Я хочу называть что-то на ViewModel, который запускает раскадровку. This blog had a promising approach to it, но на самом деле это не работает. По какой-то причине обработчик IDChanged никогда не срабатывает.Запуск анимации из ViewModel в WPF/MVVM

Я также обнаружил, что вы можете запускать анимацию на EventTriggers, но я не знаю, как поднять ее на ViewModel.

ответ

0

В результате я добавил событие AnimationStarted в мой ViewModel с ключевой строкой для какой анимации это. Затем в представлении я создаю анимацию программно, подписываюсь на событие AnimationStarted и удаляю соответствующую анимацию при ее запуске.

1

У меня есть свойство в моей виртуальной машине, которое отражает состояние приложения. Элементы в анимированном представлении имеют триггер данных, который запускает раскадровку, когда свойство VM имеет определенное значение.

+0

Я знаю, как сделать это. Вы устанавливаете триггер для запуска раскадровки при вводе условия. Но мне просто нужно сделать одноразовую анимацию: я хочу сделать быструю временную вспышку на элементе пользовательского интерфейса, чтобы привлечь к ней внимание. – RandomEngy

+0

Я не думал об этом обобщить, поэтому я не знаю, поможет ли это вам. У меня когда-то была аналогичная потребность. Я должен был «намотать» кнопку, если на минуту не было никакой активности. Я сделал это, когда к кнопке прикреплен раскадровки, раскадровка ничего не сделала ни на минуту, а затем сделала бы вспышку. В моем случае кнопка удалилась, когда щелкнула, чтобы упростить сценарий. Вспышка элемента UI для захвата внимания звучит, как только просмотр. Есть ли способ, которым представление может определить, когда к вспышке само по себе? Почему VM заботится о мигании элемента пользовательского интерфейса? Извините, это может быть не очень полезно. – Carlos

+0

Ну, несколько команд, которые срабатывают в одном окне, запускают эту вспышку в другое окно. Моя оконная модель настроена так, что VM знает о взаимоотношениях между окнами, но взглядов нет. – RandomEngy

5

Я сделал это с помощью DataTrigger и привязал его к свойству в моей модели ViewModel. Когда свойство «FlashingBackGround» получает значение «ON», начинается анимация раскадровки.

Также убедитесь, что включить в проект ссылку на "Microsoft.Expression.Interactions"

XAML: (это идет непосредственно в корневой узел)

<Window 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    x:Name="window" > 

    ... 

    <i:Interaction.Triggers> 
     <ei:DataTrigger Binding="{Binding FlashingBackground, Mode=OneWay}" Value="ON"> 
     <ei:ControlStoryboardAction Storyboard="{StaticResource MyAnimation}"  
               ControlStoryboardOption="Play"/> 
     </ei:DataTrigger> 
    </i:Interaction.Triggers> 

    ... 
</Window> 

ViewModel:

private void TurnOnFlashingBackround() 
    { 
     FlashingBackground = "ON"; 
    } 

    private string _FlashingBackround = "OFF"; 

    public string FlashingBackground 
    { 
     get { return _FlashingBackround; } 

     private set 
     { 
      if (FlashingBackground == value) 
      { 
       return; 
      } 

      _FlashingBackround = value; 
      this.OnPropertyChanged("FlashingBackground"); 
     } 
    } 

    public new event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

Наконец, модель Viewmodel должна унаследовать от "INotifyPropertyChanged"

+6

Интересный подход. Но почему бы просто не использовать 'boolean' вместо строки« ON »/« OFF »? –

+0

Обязательно добавьте также «System.Windows.Interactivity.dll». –

0

Я столкнулся с той же проблемой, и ни одна из этих должностей действительно не помогла, потому что анимации в коде, а некоторые из них были большими и сложными и требовали переменные переменные, поэтому им пришлось оставаться в коде. Я разрешил его, добавив свойства зависимостей в пользовательский элемент управления (представление), которые запускают анимацию, и привязывая их к свойствам в модели представления. Не знаю (/ care), если это что-то нарушает, потому что оно работает очень хорошо! веселит, STEPP

выдержка:

(вид) UserControl код позади:

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 

View-модель:

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