WPF MVVM - 关于属性更改的触发器故事板仅发生一次

时间:2018-05-08 12:08:19

标签: wpf animation mvvm data-binding storyboard

在我的视图模型中,我有一个计时器,需要每隔5分钟使边框背景闪烁一次。

我认为的边界:

<Border Name="btnBorder" Grid.Row="0" Grid.Column="0" Opacity="1" CornerRadius="10,10,0,0">
    <Border.Style>
        <Style TargetType="Border">
            <Style.Setters>
                <Setter Property="Background" Value="#e2e2e2"></Setter>
            </Style.Setters>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=ViewEventTrigger}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
                                    <EasingColorKeyFrame KeyTime="00:00:00.000" Value="#e2e2e2"/>
                                    <EasingColorKeyFrame KeyTime="00:00:00.500" Value="#163f6b"/>
                                    <EasingColorKeyFrame KeyTime="00:00:01.000" Value="#e2e2e2"/>
                                    <EasingColorKeyFrame KeyTime="00:00:01.500" Value="#163f6b"/>
                                    <EasingColorKeyFrame KeyTime="00:00:02.000" Value="#e2e2e2"/>
                                    <EasingColorKeyFrame KeyTime="00:00:02.500" Value="#163f6b"/>
                                    <EasingColorKeyFrame KeyTime="00:00:03.000" Value="#e2e2e2"/>
                                    <EasingColorKeyFrame KeyTime="00:00:03.500" Value="#163f6b"/>
                                    <EasingColorKeyFrame KeyTime="00:00:04.000" Value="#e2e2e2"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>

视图模型中的属性:

private string _viewEventTrigger = "";
public string ViewEventTrigger
{
    get => _viewEventTrigger ?? (_viewEventTrigger = "");
    private set
    {
        if (_viewEventTrigger == value)
            return;

        _viewEventTrigger = value;
        OnPropertyChanged();
    }
}

需要触发的方法......好吧,触发:

private void ShowInfocenterIfAnyItinirary(object sender, ElapsedEventArgs e)
{
    ViewEventTrigger = "";
    ViewEventTrigger = "True";
}

我通过使用MouseEnter触发它来测试Storyboard。但我无法通过将其绑定到我的财产来使其成功。

修改

我像这样设置了datacontext:

d:DataContext="{d:DesignInstance local:ItineraryViewModel}"

另外,我有很多其他数据绑定工作正常,比如要显示的数据和按钮的命令。但我无法让触发器执行故事。

方法ShowInfocenterIfAnyItinirary()由计时器执行,在viewmodel中启动。

计时器代码:

private readonly Timer _timer = new Timer();
public ItineraryViewModel()
{
    _timer.Interval = 5000;
    _timer.Elapsed += ShowInfocenterIfAnyItinirary;
    _timer.Start();
}

编辑2:

当程序运行时动画应该启动时,我已经延迟了。我发现动画会运行,但只运行一次。之前我没有看到它,因为窗口开始最小化。

为什么它只运行一次,无论触发事件发生多少次?

2 个答案:

答案 0 :(得分:1)

这仅设置设计时数据上下文:

d:DataContext="{d:DesignInstance local:ItineraryViewModel}"

当您实际运行应用程序时,这不会产生任何影响。

您应该将视图的DataContext 属性设置为视图模型的实例:

<Window ...>
    <Window.DataContext>
        <local:ItineraryViewModel />
    </Window.DataContext>

答案 1 :(得分:0)

我最终解决了这样的问题:

private void ShowInfocenterIfAnyItinirary(object sender, ElapsedEventArgs e)
{
    if (Items.Count <= 0) return;
    GlobalEvents.TriggerShowMainWindowEvent();
    ViewEventTrigger = "True";
    Task.Run(async () =>
    {
        Thread.Sleep(4000);
        ViewEventTrigger = "False";
    });
}

这会停止动画,而不是让它在结束点暂停。