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

发布于 2024-10-10 03:51:30 字数 2069 浏览 2 评论 0原文

编辑: 在最初的问题中,我对设置器的工作方式做出了一些错误的假设,因此我对其进行了修改,希望更加准确和有用。

我尝试使一些菜单项更加有用如果鼠标不在项目上,图标会显示为半透明,这很有趣。如果鼠标进入,图标应该动画化以完全可见。 动画有效,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 Property="Icon.Opacity" Value="0.5"/>

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

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

所以我的问题是是否有一种方法可以使其以某种方式与二传手。

(我当前的解决方法是使用单关键帧故事板,由 Loaded 事件触发,效果非常好)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听风念你 2024-10-17 03:51:30

因此,在阅读了 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 但MenuItem 中可能出现的所有图像的不透明度。

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:

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

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.

ゞ花落谁相伴 2024-10-17 03:51:30

我认为您无法像这样访问属性的属性,因此转换本身不是问题。即使图标是图像类型,仍然不起作用。例如,您可以尝试使用网格的背景不透明度。背景是网格的依赖属性,不透明度是画笔的依赖属性,但以下行将不起作用

<Grid Background.Opacity="0.8"/>

您会收到错误消息

可附加属性“不透明度”为
在“背景”类型中找不到。

您必须像这样在后台本身中设置它

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

,这意味着当您执行类似操作时,

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

您实际上正在使用 TextBlock 的附加属性前景。

图像没有名为“不透明度”的附加属性,因此您也不能执行此操作

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

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文