Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Data Triggers and Story Boards

I'm trying to trigger a progress animation when ever the ViewModel/Presentation Model is Busy. I have an IsBusy Property, and the ViewModel is set as the DataContext of the UserControl. What is the best way to trigger a "progressAnimation" storyboard when the IsBusy property is true? Blend only lets me add event triggers at the UserControl level, and I can only create property triggers in my data templates.

The "progressAnimation" is defined as a resource in the user control.

I tried adding the DataTriggers as a Style on the UserControl, but when I try to start the StoryBoard I get the following error:

'System.Windows.Style' value cannot be assigned to property 'Style' of object'Colorful.Control.SearchPanel'. A Storyboard tree in a Style cannot specify a TargetName. Remove TargetName 'progressWheel'.

ProgressWheel is the name of the object I'm trying to animate, so removing the target name is obviously NOT what I want.

I was hoping to solve this in XAML using data binding techniques, instead of having to expose events and start/stop the animation through code.

like image 613
Jonas Follesø Avatar asked Sep 17 '08 05:09

Jonas Follesø


People also ask

What are data triggers in WPF?

A trigger basically enables you to change property values or take actions based on the value of a property. So, it allows you to dynamically change the appearance and/or behavior of your control without having to create a new one.

What is a story board in WPF?

Storyboard objects use name scopes to resolve the TargetName property. For more information about WPF name scopes, see WPF XAML Namescopes. If the TargetName property is omitted, the animation targets the element on which it is defined, or, in the case of styles, the styled element.

What is double animation in WPF?

This example shows how to use a WPF animation to animate the value of a dependency property. It uses a DoubleAnimation, which is a type of animation that generates Double values, to animate the Opacity property of a Rectangle.


1 Answers

What you want is possible by declaring the animation on the progressWheel itself: The XAML:

<UserControl x:Class="TriggerSpike.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300"> <UserControl.Resources>     <DoubleAnimation x:Key="SearchAnimation" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:4"/>     <DoubleAnimation x:Key="StopSearchAnimation" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:4"/> </UserControl.Resources> <StackPanel>     <TextBlock Name="progressWheel" TextAlignment="Center" Opacity="0">         <TextBlock.Style>             <Style>                 <Style.Triggers>                     <DataTrigger Binding="{Binding IsBusy}" Value="True">                         <DataTrigger.EnterActions>                             <BeginStoryboard>                                 <Storyboard>                                     <StaticResource ResourceKey="SearchAnimation"/>                                 </Storyboard>                             </BeginStoryboard>                         </DataTrigger.EnterActions>                         <DataTrigger.ExitActions>                             <BeginStoryboard>                                 <Storyboard>                                    <StaticResource ResourceKey="StopSearchAnimation"/>                                  </Storyboard>                             </BeginStoryboard>                         </DataTrigger.ExitActions>                     </DataTrigger>                 </Style.Triggers>             </Style>         </TextBlock.Style>         Searching     </TextBlock>     <Label Content="Here your search query"/>     <TextBox Text="{Binding SearchClause}"/>     <Button Click="Button_Click">Search!</Button>     <TextBlock Text="{Binding Result}"/> </StackPanel> 

Code behind:

    using System.Windows; using System.Windows.Controls;  namespace TriggerSpike {     public partial class UserControl1 : UserControl     {         private MyViewModel myModel;          public UserControl1()         {             myModel=new MyViewModel();             DataContext = myModel;             InitializeComponent();         }          private void Button_Click(object sender, RoutedEventArgs e)         {             myModel.Search(myModel.SearchClause);         }     } } 

The viewmodel:

    using System.ComponentModel; using System.Threading; using System.Windows;  namespace TriggerSpike {     class MyViewModel:DependencyObject     {          public string SearchClause{ get;set;}          public bool IsBusy         {             get { return (bool)GetValue(IsBusyProperty); }             set { SetValue(IsBusyProperty, value); }         }          public static readonly DependencyProperty IsBusyProperty =             DependencyProperty.Register("IsBusy", typeof(bool), typeof(MyViewModel), new UIPropertyMetadata(false));            public string Result         {             get { return (string)GetValue(ResultProperty); }             set { SetValue(ResultProperty, value); }         }          public static readonly DependencyProperty ResultProperty =             DependencyProperty.Register("Result", typeof(string), typeof(MyViewModel), new UIPropertyMetadata(string.Empty));          public void Search(string search_clause)         {             Result = string.Empty;             SearchClause = search_clause;             var worker = new BackgroundWorker();             worker.DoWork += worker_DoWork;             worker.RunWorkerCompleted += worker_RunWorkerCompleted;             IsBusy = true;             worker.RunWorkerAsync();         }          void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)         {             IsBusy=false;             Result = "Sorry, no results found for: " + SearchClause;         }          void worker_DoWork(object sender, DoWorkEventArgs e)         {             Thread.Sleep(5000);         }     } } 

Hope this helps!

like image 185
Dabblernl Avatar answered Sep 21 '22 23:09

Dabblernl