在窗口中声明时EventTrigger不工作。WPF中的资源
我是WPF的新手,所以我可能遗漏了一些重要的东西,但我已经尝试并试图对以下现象做出解释,但没有成功。 基本上,以下代码起作用(显示动画):在窗口中声明时EventTrigger不工作。WPF中的资源,wpf,events,triggers,styles,Wpf,Events,Triggers,Styles,我是WPF的新手,所以我可能遗漏了一些重要的东西,但我已经尝试并试图对以下现象做出解释,但没有成功。 基本上,以下代码起作用(显示动画): ... 但是,当我尝试在下面的加载样式中放置eventrigger时,动画停止显示: <Window.Resources> <Storyboard x:Key="LoadStoryBoard" AutoReverse="True" RepeatBehavior="Forever"> <Doub
...
但是,当我尝试在下面的加载样式中放置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>
...
...
...
在触发器的样式中
不能使用带有TargetName
的对象,例如动画。为此,将它们放置在触发器模板
中。引自:
TargetName不适用于样式的触发器集合。样式没有名称范围,因此按名称引用元素是没有意义的。但是模板(DataTemplate或ControlTemplate)有一个名称范围
以下工作:
<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>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="button1" CornerRadius="0" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange" />
</Trigger>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard Storyboard="{StaticResource LoadStoryBoard}" />
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Name="TestButton" Style="{StaticResource ButtonStyle}" Width="100" Height="30" Content="Test" Grid.Column="0" Grid.Row="1" />
</Grid>
请注意,现在在边框中指定的模板中TargetName
:
注意:
或者,您可以删除情节提要。TargetName
,因为它触发的样式不受支持。您可以正确地认为事件触发器
不起作用,但这不是因为它是在参考资料
部分声明的。要看到这一点,您可以将样式直接移动到仍不起作用的按钮声明中:
<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>
因此,问题似乎与参考资料
部分中声明的情节提要
在加载
事件触发时未准备就绪有关。在中也注意到了类似的问题
然而,更让人困惑的是,如果我们随后将动画
的完整声明放入参考资料
部分中声明的样式
,那么现在样式
起作用了:
<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
,控制模板.Triggers
,数据模板.Triggers
和框架元素.Triggers
(例如按钮.Triggers
)
基本上,FrameworkElement.Triggers
TriggerCollection
中存在一个巨大的缺陷,因为它只接受EventTrigger
类型的触发器。这可以在MSDN的页面上看到,其中给出了关于此属性可以接受的内容的以下定义:
一个或多个已定义的EventTrigger元素。每一个这样的触发器都是
应包含有效的情节提要动作和引用。注意
此集合只能在页面的根元素上建立
其他触发器属性的MSDN属性页分别声明它们可以接受零个或多个TriggerBase对象,或一个或多个TriggerBase对象
此外,不同的触发器遵循不同的规则——统一的方法肯定会帮助WPF的新手。从页面:
此属性不允许您检查作为存在的触发器
此元素上正在使用的部分样式。它只报告集合
按字面意思添加到集合中的触发器的
标记或代码。元素通常不存在这样的元素
默认情况下(例如通过模板);这是更常见的
来自要在中建立的控件合成的触发器
取而代之的是风格
在行为方面(以及试图确定哪些影响来自于
哪个元素的声明触发器集合),这两个触发器
条件和触发效果可能在此元素上,或者
在逻辑树中的子元素上。请注意,如果您使用
生命周期事件,如加载以获取此集合、子
元素的触发器可能尚未完全加载,集合
将小于运行时的实际值
请注意,仅在元素上建立的触发器集合
支持EventTrigger,而不是属性触发器(Trigger)。如果你需要
属性触发器时,必须将其放置在样式或模板中,然后
然后直接将该样式或模板指定给元素
通过样式属性,或间接通过隐式样式
参考资料
从MSDN的页面:
如果要在数据模板中创建触发器,则
触发器应设置在范围内的属性
数据模板。否则,它可能更适合创建
使用针对包含数据的类型的样式触发。
例如,如果要绑定ListBox控件,则容器是
ListBoxItem对象。如果你
<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>
<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}" />