EventTrigger监听Loaded被触发了两次?
EventTrigger listening to Loaded is triggered twice?
首先,我不太确定它是否真的被触发了两次。如果在后面的代码中测试,Loaded
事件只会触发一次(甚至尝试使用 AddHandler 接受第三个参数 handledEventsToo)。但是看起来很有可能。我在 XAML 中设置了 Storyboard,当 Loaded
出现时应该 运行 一次。但是好像启动了2次,尤其是第二次是在显示window之后。
我知道,因为我在 Storyboard 中的 DoubleAnimation
上使用了附加的 属性。此附加 属性 有 1 个 属性ChangedCallback 处理程序。但是,此处理程序会使用相同的 e.NewValue
值(来自参数)触发两次。它不应该像那样被触发两次。我可以确定目标(它是动画的)并设置一些附加标志来标记已经完成的事情以防止两次触发的问题,但这也会防止其他实际触发(不是来自 Loaded
).然而,DoubleAnimation
本身是为每个触发器新创建的(因此我也无法在其上标记任何标志,因为每次触发 属性ChangedCallback 都是另一个 DoubleAnimation
的另一次,无法标记并阻止执行)。
代码如下,简单测试一下:
public class TestOwner {
public static readonly DependencyProperty TestProperty =
DependencyProperty.RegisterAttached("Test", typeof(bool), typeof(TestOwner), new PropertyMetadata(testChanged));
public static bool GetTest(DependencyObject o)
{
return (bool) o.GetValue(TestProperty);
}
public static void SetTest(DependencyObject o, bool value)
{
o.SetValue(TestProperty, value);
}
static private void testChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{ //Mark some break point here and run it, you'll see it's stopped
//here twice, the second time is right after the window is shown.
//...
}
}
XAML:
<FrameworkElement>
<FrameworkElement.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="20000" To="0"
Duration="00:00:20"
Storyboard.TargetName="someName"
local:TestOwner.Test="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</FrameworkElement.Triggers>
</FrameworkElement>
我想避免这两次触发并理解为什么会这样。
嗯,事实上 EventTrigger
只触发一次。我在问题中所说的几乎都是错误的看法。我发现看起来 Storyboard
克隆了 DoubleAnimation
,这实际上克隆了附加属性,导致 2 次进入 propertyChanged 回调处理程序。第一次是为了原作DoubleAnimation
。第二次是针对克隆的DoubleAnimation
,当Loaded
出现时,它可能实际上是克隆了运行,所以它发生在window显示之后,就像我说的之前。
至少现在我明白了这个问题,而且更多的调试告诉我,那种 2 次进入处理程序不会影响任何严重的问题。所以这个问题对我来说似乎已经解决了。
首先,我不太确定它是否真的被触发了两次。如果在后面的代码中测试,Loaded
事件只会触发一次(甚至尝试使用 AddHandler 接受第三个参数 handledEventsToo)。但是看起来很有可能。我在 XAML 中设置了 Storyboard,当 Loaded
出现时应该 运行 一次。但是好像启动了2次,尤其是第二次是在显示window之后。
我知道,因为我在 Storyboard 中的 DoubleAnimation
上使用了附加的 属性。此附加 属性 有 1 个 属性ChangedCallback 处理程序。但是,此处理程序会使用相同的 e.NewValue
值(来自参数)触发两次。它不应该像那样被触发两次。我可以确定目标(它是动画的)并设置一些附加标志来标记已经完成的事情以防止两次触发的问题,但这也会防止其他实际触发(不是来自 Loaded
).然而,DoubleAnimation
本身是为每个触发器新创建的(因此我也无法在其上标记任何标志,因为每次触发 属性ChangedCallback 都是另一个 DoubleAnimation
的另一次,无法标记并阻止执行)。
代码如下,简单测试一下:
public class TestOwner {
public static readonly DependencyProperty TestProperty =
DependencyProperty.RegisterAttached("Test", typeof(bool), typeof(TestOwner), new PropertyMetadata(testChanged));
public static bool GetTest(DependencyObject o)
{
return (bool) o.GetValue(TestProperty);
}
public static void SetTest(DependencyObject o, bool value)
{
o.SetValue(TestProperty, value);
}
static private void testChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{ //Mark some break point here and run it, you'll see it's stopped
//here twice, the second time is right after the window is shown.
//...
}
}
XAML:
<FrameworkElement>
<FrameworkElement.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="20000" To="0"
Duration="00:00:20"
Storyboard.TargetName="someName"
local:TestOwner.Test="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</FrameworkElement.Triggers>
</FrameworkElement>
我想避免这两次触发并理解为什么会这样。
嗯,事实上 EventTrigger
只触发一次。我在问题中所说的几乎都是错误的看法。我发现看起来 Storyboard
克隆了 DoubleAnimation
,这实际上克隆了附加属性,导致 2 次进入 propertyChanged 回调处理程序。第一次是为了原作DoubleAnimation
。第二次是针对克隆的DoubleAnimation
,当Loaded
出现时,它可能实际上是克隆了运行,所以它发生在window显示之后,就像我说的之前。
至少现在我明白了这个问题,而且更多的调试告诉我,那种 2 次进入处理程序不会影响任何严重的问题。所以这个问题对我来说似乎已经解决了。