有没有办法为样式属性使用样式设置器?

时间:2011-01-02 04:27:53

标签: wpf xaml controls styles

编辑 在原始问题中,我对setter的工作方式做了一些错误的假设,因此我对其进行了修改,以期更加准确和有用。

如果鼠标不在项目上方,我试图通过使图标显示为半透明来使一些菜单项更有趣。如果鼠标进入,则应该将图标设置为动画以使其完全可见。 动画工作,Storyboard.TargetProperty允许直接访问图标的不透明属性:

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

如果我尝试使用setter作为初始图标不透明度,代码将无法编译:

<Setter Property="Icon.Opacity" Value="0.5"/>

修改 Setter不按照我尝试使用它们的方式工作,您无法访问属性的属性(请参阅答案) 如果尚未设置样式的目标类型,则唯一可以指定的是目标类,以下样式应该是等效的:

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

所以我的问题是,是否有办法让它以某种方式与setter一起工作。

(我目前的解决方案是使用Loaded事件触发的单关键帧故事板,效果非常好。

2 个答案:

答案 0 :(得分:1)

我认为您不能像这样访问属性的属性,因此转换本身不是问题所在。即使Icon是Type Image仍然无法正常工作。例如,您可以尝试使用背景不透明度来表示网格。背景是网格的依赖属性,不透明度是Brush的依赖属性,但以下行不起作用

<Grid Background.Opacity="0.8"/>

你会收到一个错误

  

可附加属性'Opacity'是   在'背景'类型中找不到。

您必须在背景中设置此项

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

所以这意味着当你做这样的事情时

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

您实际上正在使用附加属性前台进行TextBlock。

图片没有名为Opacity的附加属性,因此您无法执行此操作

<MenuItem Image.Opacity="0.8" />

除了你正在做的另一个解决方法是使用这样的东西(最顶层的MenuItem或你想用它的任何地方)。

<MenuItem x:Name="topMenuItem"
          ...>
    <MenuItem.Resources>
        <Style TargetType="Image">
            <Setter Property="Opacity" Value="0.5"/>
        </Style>
    </MenuItem.Resources>
    <!-- ... -->
</MenuItem>

答案 1 :(得分:1)

因此,在阅读了Meleak的回答并发现你可以通过资源在一个风格中拥有一种风格时,最接近于使用setter这样做是一种嵌入式风格来访问图标的不透明度。在这里我假设图标是一个图像所以我用它作为目标类型,因此完整的样式看起来像这样:

<Style x:Key="MenuItemMouseOverStyle" TargetType="MenuItem">
    <Style.Resources>
        <Style TargetType="Image">
            <Setter Property="Opacity" Value="0.5"/>
        </Style>
    </Style.Resources>
    <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>

唯一的问题是它实际上并没有设置Icon.Opacity,而是菜单项中可能出现的所有图像的不透明度。