WPF - Создание условия выполнения анимации для свойства привязанного элемента данных

У меня есть объект данных - пользовательский класс с именемNotification - это разоблачаетIsCritical имущество. Идея заключается в том, что если срок действия уведомления истечет, у него есть срок действия и пользовательНа это следует обратить внимание.

Представьте себе сценарий с этими данными теста:

_source = new[] {
    new Notification { Text = "Just thought you should know" },
    new Notification { Text = "Quick, run!", IsCritical = true },
  };

Второй пункт должен появиться вItemsControl с пульсирующим фоном. Вот'Это простая выдержка из шаблона данных, в которой показаны средства, с помощью которых я думал об анимации фона между серым и желтым.


  
    
      
        
          
            
          
        
      
    
    
  

Что я'Я не уверен, как сделать эту анимацию обусловленной значениемIsCritical, Если связанное значениеfalseтогда цвет фона по умолчанию#DDD должны быть сохранены.

Ответы на вопрос(5)

Я хотел бы создать две DataTemplates и использовать DataTemplateSelector. Ваш XAML будет выглядеть примерно так:



    
        
            
                
                    
                        
                            
                        
                    
                
            
            
        
    
    
        
            
        
    


    
        
    


    

И DataTemplateSelector будет выглядеть примерно так:

class CriticalItemSelector : DataTemplateSelector
{
    public DataTemplate Critical
    {
        get;
        set;
    }

    public DataTemplate NonCritical
    {
        get;
        set;
    }

    public override DataTemplate SelectTemplate(object item, 
            DependencyObject container)
    {
        Message message = item as Message;
        if(item != null)
        {
            if(message.IsCritical)
            {
                return Critical;
            }
            else
            {
                return NonCritical;
            }
        }
        else
        {
            return null;
        }
    }
}

Таким образом, WPF автоматически установит все, что критично для шаблона с анимацией, а все остальное будет другим шаблоном. Это также является общим в том смысле, что позже вы можете использовать другое свойство для переключения шаблонов и / или добавления большего количества шаблонов (схема с низкой / нормальной / высокой важностью).

 Drew Noakes29 авг. 2009 г., 20:14
Это интересный ответ, но этоне такой гибкий, как ямне нравится Например, что если в шаблоне данных есть несколько элементов, которые нужно анимировать в зависимости от состояния различных свойств? В моем случае и сам шаблон данных гораздо сложнее, чем просто так что я'через это введу много дубликатов в мой XAML. Может подойти некоторым людям, хотя. +1 за подробное объяснение!
Решение Вопроса

Последняя часть этой головоломки ...DataTriggers, Все, что вам нужно сделать, это добавить один DataTrigger к вашему DataTemplate, привязать его к свойству IsCritical и всякий раз, когда он 'правда, в этомs EnterAction / ExitAction вы запускаете и прекращаете выделять раскадровку. Вот полностью рабочее решение с некоторыми жестко закодированными ярлыками (вы определенно можете сделать лучше):

Xaml:


  
    
      
        
      
      
        
          
            
              
                
              
            
          
          
            
          
        
      
    
  
  
    
      
      
    
    
    
  

Код позади:

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;

namespace WpfTest
{
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();
      DataContext = new NotificationViewModel();
    }

    private void ToggleImportance_Click(object sender, RoutedEventArgs e)
    {
      ((NotificationViewModel)DataContext).ToggleImportance();
    }
  }

  public class NotificationViewModel
  {
    public IList Notifications
    {
      get;
      private set;
    }

    public NotificationViewModel()
    {
      Notifications = new List
                        {
                          new Notification
                            {
                              Text = "Just thought you should know"
                            },
                          new Notification
                            {
                              Text = "Quick, run!",
                              IsCritical = true
                            },
                        };
    }

    public void ToggleImportance()
    {
      if (Notifications[0].IsCritical)
      {
        Notifications[0].IsCritical = false;
        Notifications[1].IsCritical = true;
      }
      else
      {
        Notifications[0].IsCritical = true;
        Notifications[1].IsCritical = false;
      }
    }
  }

  public class Notification : INotifyPropertyChanged
  {
    private bool _isCritical;

    public string Text { get; set; }

    public bool IsCritical
    {
      get { return _isCritical; }
      set
      {
        _isCritical = value;
        InvokePropertyChanged("IsCritical");
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void InvokePropertyChanged(string name)
    {
      var handler = PropertyChanged;
      if (handler != null)
      {
        handler(this, new PropertyChangedEventArgs(name));
      }
    }
  }
}

Надеюсь это поможет :).

 Drew Noakes02 сент. 2009 г., 19:20
@Anvanka - спасибо за это. Я не имелДо этого использовали DataTrigger EnterActions или ExitActions. Спасибо также за подробный пример - отличный ответ и достойный награды.
 Anvaka02 сент. 2009 г., 22:43
Добро пожаловать :). Я'Я рад, что смог помочь.

В этом случае вы используете триггеры стиля. (Я'я делаю это по памяти, поэтому могут быть некоторые ошибки)

  
    
      
        
         
            
              
                
                  
                
              
            
         
        
        
    
  
 Drew Noakes02 сент. 2009 г., 19:22
Спасибо все равно. Если ты'Заинтересован, был дан элегантный ответ, который показывает, как это сделать.
 Will18 авг. 2009 г., 17:35
Ну, это будет немного сложнее, чем я могу решить прямо сейчас. Я'я уверен, что естьспособ сделать это, но выВозможно, мне придется пойти по этому пути совершенно другим путем. Хорошая возможность прочитать о триггерах ...
 Drew Noakes18 авг. 2009 г., 17:12
Выглядит многообещающе, спасибо. Позвольте мне попробовать и вернуться к вам.
 Will28 авг. 2009 г., 19:12
мы поиграли с ним пару раз без особого успеха.
 Drew Noakes18 авг. 2009 г., 17:18
Нет, нет работа. Получите ошибку:Property Setter 'Triggers' cannot be set because it does not have an accessible set accessor.
 Drew Noakes28 авг. 2009 г., 17:09
К вашему сведению - яМы открыли щедрость на этот вопрос, на случай, если вы захотите вернуться к ней.

Вот'Решение, которое запускает анимацию только тогда, когда входящее обновление свойства имеет определенное значение. Полезно, если вы хотите нарисовать пользователяОбратите внимание на анимацию, но после этого пользовательский интерфейс должен вернуться к ней.состояние по умолчанию.

Предполагая, что IsCritical связан с элементом управления (или даже с невидимым элементом управления), вы добавляете NotifyOnTargetUpdated к привязке и привязываете EventTrigger к событию Binding.TargetUpdated. Затем вы расширяете элемент управления, чтобы запускать событие TargetUpdated только тогда, когда входящее значение является тем, которое вас интересует. Итак ...

public class CustomTextBlock : TextBlock
    {
        public CustomTextBlock()
        {
            base.TargetUpdated += new EventHandler(CustomTextBlock_TargetUpdated);
        }

        private void CustomTextBlock_TargetUpdated(object sender, DataTransferEventArgs e)
        {
            // don't fire the TargetUpdated event if the incoming value is false
            if (this.Text == "False") e.Handled = true;
        }
    }

и в файле XAML ..


..

..


  
    ..
  



С ColorAnimation это кажется странностью, так как он отлично работает с DoubleAnimation. Тебе нужно для простоты указать раскадровкиИмя_целевого_объекта» свойство работать с ColorAnimation

    

    

        
            
                
                    
                        
                            
                        
                    
                
            
        

        
            
        

    




    

 Drew Noakes02 сент. 2009 г., 19:21
@TFD - спасибо за ваш ответ. С вашим редактированием это соответствует моим потребностям, но @Anvanka дал вам правильный ответ (в основном тот же самый), поэтому я дал его ему. +1 все тоже самое.

Ваш ответ на вопрос