EventTrigger, прослушивающий Loaded, срабатывает дважды?

Во-первых, я не совсем уверен, действительно ли он срабатывает дважды. Событие Loaded, если оно проверено в коде, запускается только один раз (даже пытались использовать AddHandler, принимая третий аргумент handledEventsToo). Однако это выглядит очень вероятным. У меня есть настройка раскадровки в XAML, и ее нужно запускать только один раз, когда поднимается Loaded. Но вроде со 2 раза запускается, особенно второй раз сразу после показа окна.

Я знаю это, потому что у меня есть прикрепленное свойство, используемое для DoubleAnimation внутри раскадровки. Это присоединенное свойство имеет 1 обработчик propertyChangedCallback. Однако этот обработчик запускается дважды с одним и тем же значением e.NewValue (из аргумента). Это не должно срабатывать дважды, как это. Я могу определить цель (анимированную) и установить прикрепленный флаг, чтобы отметить, что с ней что-то было сделано, чтобы предотвратить проблему двойного срабатывания, но это также предотвратит другие фактические триггеры (которые не из Loaded). Однако сам DoubleAnimation создается заново для каждого триггера (поэтому я также не могу пометить на нем какой-либо флаг, потому что каждый раз, когда запускается propertyChangedCallback, это еще один раз другого 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>

Я хотел бы избежать этого дважды, а также понять, почему это так.


person Hopeless    schedule 21.07.2015    source источник


Ответы (1)


Ну, на самом деле EventTrigger срабатывает только один раз. Почти то, что я сказал в своем вопросе, является неправильным восприятием. Я обнаружил, что похоже, что Storyboard клонирует DoubleAnimation, и это на самом деле клонирует даже прикрепленные свойства, вызывая 2 раза вход в обработчик обратного вызова propertyChanged. Первый раз для оригинального DoubleAnimation. Второй раз для клонированного DoubleAnimation, он может быть фактически клонирован и запущен, когда Loaded поднимается, поэтому это происходит сразу после отображения окна, как я сказал ранее.

По крайней мере, теперь я понимаю проблему, а также дальнейшая отладка показала мне, что такой 2-кратный вход в обработчик не повлияет на какую-либо серьезную проблему. Так что эта проблема мне кажется решенной.

person Hopeless    schedule 21.07.2015