Ссылка на объект раскадровки WPF - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть пользовательский контроль, который является формой сердца, которое мне нужно побить. Вот мой код:

<userControls:Heart x:Name="Heartbeat" Width="25" Height="25">
   <userControls:Heart.Resources>
       <Storyboard x:Key="HeartbeatStoryboard2X"
              RepeatBehavior="2x"
              Completed="Storyboard_Completed">
            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                             Storyboard.Target="{Binding ElementName=Heartbeat}"
                                             From="0.05" To="0.8" Duration="0:0:0.500">
            </DoubleAnimation>
            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                  Storyboard.Target="{Binding ElementName=Heartbeat}"
                  From="0.8" To="0.05" Duration="0:0:1.500">
                <DoubleAnimation.EasingFunction>
                     <PowerEase EasingMode="EaseOut" Power="6" />
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </userControls:Heart.Resources>
    <userControls:Heart.Style>
         <Style TargetType="userControls:Heart">
             <Style.Triggers>
                   <DataTrigger Binding="{Binding IsHeartBeating}" Value="True">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Name="HeartbeatStoryboard"/>
                             </DataTrigger.EnterActions>
                   </DataTrigger>
          </Style.Triggers>
     </Style>
  </userControls:Heart.Style>

Код в коде:

    public bool IsHeartBeating { get; set; }
    private bool m_restartedAnimation = false;
    private void Storyboard_Completed(object sender, EventArgs e)
    {
        ClockGroup clockGroup = sender as ClockGroup;
        Storyboard heartbeatStoryboard = clockGroup.Timeline as Storyboard;
        if (IsHeartBeating == true)
        {
            m_restartedAnimation = true;
            heartbeatStoryboard.Begin();
        }
        else
        {
            if (m_restartedAnimation == true)
            {
                heartbeatStoryboard.Stop();
            }
            m_restartedAnimation = false;
        }
    }

Я получаю две ошибки:

MC3093 Невозможно установить значение атрибута имени «HeartbeatStoryboard» для элемента «BeginStoryboard». «BeginStoryboard» находится в области действия элемента «Heart», имя которого уже зарегистрировано, когда оно было определено в другой области.

и

XDG0062 Должен иметь ссылку на объект Storyboard перед выполнением этого действия триггера.

У моего сердца нет набора Имени.
Есть идеи? ТИА

1 Ответ

1 голос
/ 06 апреля 2020

Вы говорите, что ваше сердце не имеет установленного имени, но вы дважды ссылаетесь на него в раскадровке с ElementName=Heartbeat? В любом случае проблема заключается в следующей строке:

<BeginStoryboard Name="HeartbeatStoryboard"/>

Это просто дает имя элементу временной шкалы BeginStoryboard, я подозреваю, что вы на самом деле намеревались это:

<BeginStoryboard Storyboard="{StaticResource HeartbeatStoryboard2X}"/>

ОБНОВЛЕНИЕ: если присмотреться, на самом деле есть несколько проблем, хотя мне нужно было бы увидеть MCVE для их правильного решения. Прежде всего, вы уже запускаете раскадровку в стиле вашего элемента управления, поэтому вам не нужно устанавливать Storyboard.Target. И даже если бы это было так, то и Storyboard должны быть установлены и на Storyboard.TargetProperty, а не на анимации. Наконец, когда вы вызываете heartbeatStoryboard.Begin и heartbeatStoryboard.Stop, вам нужно передать элемент (т.е. this.Heartbeat).

Таким образом, ваш XAML должен выглядеть примерно так:

<Storyboard x:Key="HeartbeatStoryboard2X"
         RepeatBehavior="2x"
         Completed="Storyboard_Completed"
      Storyboard.TargetProperty="Opacity">
    <DoubleAnimation From="0.05" To="0.8" Duration="0:0:0.500" />
    <DoubleAnimation From="0.8" To="0.05" Duration="0:0:1.500">
        <DoubleAnimation.EasingFunction>
            <PowerEase EasingMode="EaseOut" Power="6" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
</Storyboard>

Ваш обработчик раскадровки не должен выглядеть так:

private void Storyboard_Completed(object sender, EventArgs e)
{
    ClockGroup clockGroup = sender as ClockGroup;
    Storyboard heartbeatStoryboard = clockGroup.Timeline as Storyboard;
    if (viewModel.IsHeartBeating == true)
    {
        m_restartedAnimation = true;
        heartbeatStoryboard.Begin(this.Heartbeat);
    }
    else
    {
        if (m_restartedAnimation == true)
        {
            heartbeatStoryboard.Stop(this.Heartbeat);
        }
        m_restartedAnimation = false;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...