Edit: In the original question i made some wrong assumptions about how setters work so i modified it to hopefully be more accurate and useful.
I have tried to make some menu items more interesting by having the icons appear half-transparent if the mouse is not over the item. If the mouse enters, the icon should be animated to become completely visible.
The animations work, Storyboard.TargetProperty
allows direct access to the icon's opacity property:
<Style x:Key="MenuItemMouseOverStyle" TargetType="MenuItem">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Icon.Opacity">
<EasingDoubleKeyFrame KeyTime="0" Value="0.5"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Icon.Opacity">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.5"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
If i try to use a setter for the initial icon-opacity the code won't compile:
<Setter Property="Icon.Opacity" Value="0.5"/>
Edit: Setters do not work the way i tried to use them, you cannot access the properties of properties (see answers) The only thing you can do is specify a target class if the target type of the style has not been set, the following styles should be equivalent:
<Style x:Key="Style1" TargetType="Image">
<Setter Property="Opacity" Value="0.5"/>
</Style>
<Style x:Key="Style2">
<Setter Property="Image.Opacity" Value="0.5"/>
</Style>
So my question is if there is a way to make this somehow work with a setter.
(My current work-around is a single-keyframe storyboard that is triggered with the Loaded
event which works quite well)
I don't think you can access a Property of a Property like that so the casting itself isn't the problem. Even if Icon was of Type Image that still wouldn't work. You can try with Backgrounds Opacity for a Grid for example. Background is a Dependency Property for Grid and Opacity is a Dependency Property for Brush but the following line won't work
You'll get an error saying
You would have to set this in the Background itself like this
So what this means as when you do something like this
you're actually using the Attached Property Foreground for TextBlock.
Image doesn't have an Attached Property called Opacity so you can't do this either
Another workaround besides the one you're already doing is to use something like this (top-most MenuItem or wherever you want to use it).
So after reading Meleak's answer and finding out that you can have a style within a style via resources what probably comes closest to doing this with a setter is an embedded style to access the icon's opacity. Here i assume the icon to be an image so i use that as the target type, the complete style hence looks like this:
The only problem with this is that it does not actually set the
Icon.Opacity
but the opacity of all images that may occur within the MenuItem.