Анимация раскадровки на элементе внутри TabItem не останавливается при смене вкладок - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть TabControl с динамически созданным TabItems, каждый из которых содержит элемент Border, который мне нужно анимировать (сделать рамку fla sh От желтого до оранжевого), когда свойство в модели представления больше нуля через привязку данных, но остаются черными, если значение равно нулю. Каждый TabItem имеет свой собственный экземпляр модели представления, поэтому значение свойства может быть разным для каждого TabItem, поэтому анимацию следует активировать только на соответствующем TabItem (т. Е. Каждый TabItem является UserControl, который содержит несколько Border элементов, один из которых я sh должен анимировать, вызванный значением свойства в UserControl s viewmodel).

У меня есть несколько аналогичных элементов, поэтому я использую MultiDataTrigger чтобы проверить tag элемента, а также проверить значение свойства (через конвертер).

Я могу успешно анимировать BorderBrush при выборе TabItem, где значение свойства равно больше нуля, но когда я затем выбираю TabItem, где значение свойства равно нулю, анимация должна остановиться, но это не так. Я также изменяю BorderThickness и Margin, и эти настройки возвращаются к нормальным настройкам, как и ожидалось, но анимация не останавливается.

Я использую Style.Trigger для применения анимации, и конвертер для преобразования значения свойства из int в boolean (true, если больше нуля, и false, если ноль).

Вот мой код xaml (из app.xaml):

    <Style TargetType="{x:Type Border}" x:Key="JobFilterExternalBorder">
        <Setter Property="BorderThickness" Value="3"/>
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="CornerRadius" Value="3"/>
        <Setter Property="Margin" Value="2,0,1,0.8"/>
        <Style.Triggers>
            <!-- Add Data Trigger to identify if filter is UnprocessedParts and value is > 0, and animate border to imitate a flashing border -->
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag}" Value="IsUnprocessed"/>
                    <Condition Binding="{Binding UnprocessedQty, Converter={StaticResource ConvertNonZeroToBoolean}}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="BorderThickness" Value="6"/>
                    <Setter Property="Margin" Value="0,-2,-1,-1.2"/>
                </MultiDataTrigger.Setters>
                <MultiDataTrigger.EnterActions>
                    <BeginStoryboard Name="FlashStoryboard" Storyboard="{StaticResource AnimationFlashYellowToOrange}">
                    </BeginStoryboard>
                </MultiDataTrigger.EnterActions>
                <MultiDataTrigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="FlashStoryBoard" />
                    <RemoveStoryboard BeginStoryboardName="FlashStoryBoard"/>
                </MultiDataTrigger.ExitActions>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>

И мой Storyboard:

    <Storyboard x:Key="AnimationFlashYellowToOrange" Storyboard.TargetProperty="BorderBrush" RepeatBehavior="Forever" Duration="0:0:1" FillBehavior="Stop">
        <ObjectAnimationUsingKeyFrames>
            <DiscreteObjectKeyFrame KeyTime="0:0:0">
                <DiscreteObjectKeyFrame.Value>
                    <SolidColorBrush Color="Yellow" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame KeyTime="0:0:0.5">
                <DiscreteObjectKeyFrame.Value>
                    <SolidColorBrush Color="Orange" />
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>

И представление, к которому это применяется:

    <Border Name="UnprocessedQtyBorder" Tag="IsUnprocessed" Style="{StaticResource JobFilterExternalBorder}" >
    </Border>

Я могу подтвердить, что MultiDataTrigger работает нормально, потому что BorderThickness и возвращается к нормальной толщине, когда MultiDataTrigger становится ложным при выборе TabItem, где значение свойства равно нулю. Это просто анимация, которая не останавливается.

Я пробовал:

  • Добавление StopStoryboard в MultiDataTrigger.ExitActions
  • Добавление RemoveStoryboard к MultiDataTrigger.ExitActions
  • Включая FillBehaviour="Stop"
  • Добавление секунды MultiDataTrigger для запуска нового раскадровки, который устанавливает BorderBrush в черный цвет
  • Изменение порядок Style настроек, чтобы иметь MultiDataTrigger перед стандартными настройками свойств
  • Поиск в inte rnet любых других примеров, которые могли бы указать мне правильное направление

Мне нужно, чтобы раскадровка анимировала границу непрерывно, пока на экране присутствует элемент, вызывающий беспокойство, поэтому я включил свойство RepeatBehavior="Forever"

. Я следую шаблону проектирования MVVM и предпочел бы избежать использования кода позади , но я не усердствую по этому поводу.

Я боролся с этим весь день и не добился никакого прогресса, так что это моя последняя надежда.

РЕДАКТИРОВАТЬ: Я подозреваю, что MultiDataTrigger.ExitActions никогда не выполняются, чтобы остановить Storyboard, поэтому необходимо задать дополнительный вопрос; Можно ли вообще остановить раскадровку таким образом? Может ли MultiDataTrigger.ExitActions быть запущен для выполнения другим способом?

EDIT2: Я создал образец решения VS, чтобы продемонстрировать эффект, который я вижу. Решение можно найти на GitHub здесь

EDIT3: Вот что сейчас происходит: enter image description here

При возврате к «Tab 1» анимация должна остановиться.

...