gpt4 book ai didi

wpf - 在 WPF 中的 Window.Resources 中声明 EventTrigger 时不起作用

转载 作者:行者123 更新时间:2023-12-04 14:18:52 25 4
gpt4 key购买 nike

我是 WPF 的新手,所以我可能会遗漏一些重要的东西,但我已经尝试过并试图对以下现象提出解释,但无济于事。
基本上,以下代码有效(显示动画):

    <Window.Resources>
<Storyboard x:Key="LoadStoryBoard"
AutoReverse="True"
RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="button1"
Storyboard.TargetProperty="(Button.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.4" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
...
<Button x:Name="button1" Grid.Column="0" Grid.Row="1" Style="{StaticResource Load}">
<Button.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource LoadStoryBoard}" />
</EventTrigger>
</Button.Triggers>
</Button>

但是,当我尝试将 eventrigger 放入以下加载样式时,动画不再出现:
    <Window.Resources>
<Storyboard x:Key="LoadStoryBoard"
AutoReverse="True"
RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="button1"
Storyboard.TargetProperty="(Button.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0.4" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
...
<Style x:Key="Load" TargetType="Button">
...
<Style.Triggers>
...
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource LoadStoryBoard}" />
</EventTrigger>
</Style.Triggers>
</Style>

最佳答案

您是正确的 EventTrigger不起作用,但这不是因为它是在 Resources 中声明的部分。要看到这一点,您可以将您的样式直接移至 Button仍然不起作用的声明:

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

但是,如果我们移动 Animation 的声明来自 Resources部分,它再次起作用:
<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>

因此,问题似乎与 Storyboard 有关。在 Resources 中声明部分尚未准备好 Loaded事件触发。在 this post 中记录了一个类似的问题.

然而,为了让事情更加困惑,如果我们为 Animation 加上完整的声明进 StyleResources 中声明部分,然后是 Style作品:
<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}" />

我可以推测为什么会发生这种情况,但我猜很少有 WPF 开发人员真正知道为什么一切都是这样的......我已经了解到,如果特定的声明方法有效,请使用它并如果没有,请尝试不同的。

背景

在WPF中,有四个地方可以定义 Triggers ; Style.Triggers , ControlTemplate.Triggers , DataTemplate.TriggersFrameworkElement.Triggers (例如 Button.Triggers )。

基本上, FrameworkElement.Triggers 存在一个巨大的缺陷。 TriggerCollection因为它只接受 EventTrigger 类型的触发器.这可以在 FrameworkElement.Triggers Property 上看到MSDN 上的页面,其中给出了有关此属性可以接受的内容的以下定义:

One or more defined EventTrigger elements. Each such trigger is expected to contain valid storyboard actions and references. Note that this collection can only be established on the root element of a page.



其他触发器属性的 MSDN 属性页均声明它们可以接受零个或多个 TriggerBase 对象,或者一个或多个 TriggerBase 对象。

此外,不同的触发器遵循不同的规则 - 统一的方法肯定会对 WPF 的新手有所帮助。来自 FrameworkElement.Triggers Property页:

This property does not enable you to examine triggers that exist as part of styles in use on this element. It only reports the collection of triggers that are literally added to the collection, either in markup or code. Elements do not typically have such elements existing by default (through a template for instance); it is more common for triggers that come from control compositing to be established in styles instead.

In terms of behavior (and trying to establish which effect came from which element's declared Triggers collection), both the triggering condition and the trigger effect might be on this element, or might be on its child elements in the logical tree. Note that if you use lifetime events such as Loaded to get this collection, the child element's triggers might not yet be fully loaded, and the collection will be smaller than it would truly be at run time.

Note that the collection of triggers established on an element only supports EventTrigger, not property triggers (Trigger). If you require property triggers, you must place these within a style or template and then assign that style or template to the element either directly through the Style property, or indirectly through an implicit style reference.



来自 DataTemplate.Triggers Property MSDN 页面:

If you are creating triggers within a data template, the setters of the triggers should be setting properties that are within the scope of the data template. Otherwise, it may be more suitable to create triggers using a style that targets the type that contains the data. For example, if you are binding a ListBox control, the containers are ListBoxItem objects. If you are using triggers to set properties that are not within the scope of the DataTemplate, then it may be more suitable to create a ListBoxItem style and create triggers within that style.



不幸的是,所有这些额外信息实际上并没有回答您关于为什么动画资源在 Style 中不起作用的问题。资源,但希望现在,您可以看到整个 Trigger区域是一个有点复杂,凌乱的区域。我自己不是专家,我只是倾向于使用任何一种声明方式 Trigger是有效的。

我希望这在某种程度上有所帮助。

关于wpf - 在 WPF 中的 Window.Resources 中声明 EventTrigger 时不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17801348/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com