Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to use a style setter for properties of properties?

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)

like image 573
H.B. Avatar asked Nov 05 '22 04:11

H.B.


1 Answers

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

<Grid Background.Opacity="0.8"/>

You'll get an error saying

The attachable property 'Opacity' was not found in type 'Background'.

You would have to set this in the Background itself like this

<Grid>
    <Grid.Background>
        <SolidColorBrush Opacity="0.8"/>
    </Grid.Background>
</Grid>

So what this means as when you do something like this

<Grid TextBlock.Foreground="Red">
    <TextBlock Text="Test"/>
</Grid>

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

<MenuItem Image.Opacity="0.8" />

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).

<MenuItem x:Name="topMenuItem"
          ...>
    <MenuItem.Resources>
        <Style TargetType="Image">
            <Setter Property="Opacity" Value="0.5"/>
        </Style>
    </MenuItem.Resources>
    <!-- ... -->
</MenuItem>
like image 189
Fredrik Hedblad Avatar answered Nov 09 '22 13:11

Fredrik Hedblad