You are correct that EventTrigger does not work, but that is not because it was declared in the Resources section. To see this, you can drag your style directly into a Button declaration, where it still doesn't work:
<Button x:Name="button1" Grid.Column="0" Grid.Row="1"> <Button.Style> <Style TargetType="Button"> <Style.Triggers> <EventTrigger RoutedEvent="Button.Loaded"> <BeginStoryboard Storyboard="{StaticResource LoadStoryBoard}" /> </EventTrigger> </Style.Triggers> </Style> </Button.Style> </Button>
However, if we move the Animation ad from the Resources section, it will work again:
<Button x:Name="button1" Grid.Column="0" Grid.Row="1"> <Button.Style> <Style TargetType="Button"> <Style.Triggers> <EventTrigger RoutedEvent="Button.Loaded"> <BeginStoryboard> <Storyboard AutoReverse="True" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Button.Opacity)"> <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.4" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger> </Style.Triggers> </Style> </Button.Style> </Button>
The problem seems to be related to the Storyboard declared in the Resources section, not ready at the time of the Loaded event. A similar problem is noted in this post .
However, just to make things more confusing, if we put the full announcement for Animation in Style , declared in the Resources section, now Style works:
<Window.Resources> <Style x:Key="Load" TargetType="Button"> <Style.Triggers> <EventTrigger RoutedEvent="Button.Loaded"> <BeginStoryboard> <Storyboard AutoReverse="True" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Button.Opacity)"> <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.4" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger> </Style.Triggers> </Style> </Window.Resources> <Button x:Name="button1" Grid.Column="0" Grid.Row="1" Style="{StaticResource Load}" />
I could have guessed why this is happening, but I assume that there are very few WPF developers who really know why everything is as it is ... I found out that if a certain ad method works, use it, and if not, try other.
Background
There are four places in WPF where we can define Triggers ; Style.Triggers , ControlTemplate.Triggers , DataTemplate.Triggers and FrameworkElement.Triggers (e.g. Button.Triggers ).
Basically, there is a big flaw in the FrameworkElement.Triggers TriggerCollection , since it only accepts triggers of the EventTrigger type. This can be seen on the FrameworkElement.Triggers Property page on MSDN, which indicates the following definition of what this property can accept:
One or more specific EventTrigger elements. Each such trigger is expected to contain valid actions and links to the storyboard. Please note that this collection can only be installed on the root element of the page.
The MSDN property pages for other trigger properties report that they can accept Zero or more TriggerBase objects or one or more TriggerBase objects.
In addition, there are different rules that different triggers follow - a single approach would undoubtedly help WPF newbies. From the FrameworkElement.Triggers Property page:
This property does not allow you to view triggers that exist as part of the styles used in this element. It only reports a collection of triggers that are literally added to the collection, either to markup or code. Elements usually do not have such elements by default (via a template, for example); It is more common for triggers that come from control compositing, which will be set in styles.
From the point of view of behavior (and attempts to establish which effect came from which element the trigger collection is declared), how the trigger condition and the effect of the trigger can be on this element or can be on its children in the logical tree. Please note that if you use ones such as “Downloaded” to get this collection, the child triggers for the elements cannot yet be fully loaded, and the collection will be smaller than it would be at run time.
Note that the set of triggers set only for an element supports EventTrigger, not property triggers (trigger). If you need property triggers, you must put them in a style or template and then assign this style or template to the element either directly through the Style property, or indirectly through an implicit link style.
On the DataTemplate.Triggers Property page on MSDN:
If you create triggers in a data template, setter triggers must set properties that fall within the scope of the data template. Otherwise, there may be more triggers using a style intended for the type containing the data. For example, if you bind a ListBox control, containers ListBoxItem objects. If you use triggers to set properties that are not part of the DataTemplate, then this might be more suitable for creating a ListBoxItem style and creating triggers within that style.
Unfortunately, all this additional information does not actually answer your question about why the animation resource does not work in the Style resource, but hopefully you can now see that the entire Trigger area is a bit complicated, dirty area. Not being an expert myself, I just try to use any Trigger declaration method that works.
I hope this helps.