WPF MVVM - 在 属性 更改时触发情节提要仅发生一次
WPF MVVM - Trigger storyboard on property change only happens once
在我的视图模型中,我有一个计时器需要每 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 来测试它。但是我无法通过将它绑定到我的 属性.
来使其工作
编辑:
我这样设置数据上下文:
d:DataContext="{d:DesignInstance local:ItineraryViewModel}"
此外,我还有很多其他数据绑定可以正常工作,例如要显示的数据和按钮命令。但是我就是不能让触发器执行故事情节。
方法ShowInfocenterIfAnyItinirary()
由计时器执行,在视图模型中启动。
定时器代码:
private readonly Timer _timer = new Timer();
public ItineraryViewModel()
{
_timer.Interval = 5000;
_timer.Elapsed += ShowInfocenterIfAnyItinirary;
_timer.Start();
}
编辑 2:
我已经延迟了动画应该在程序 运行 时开始。我发现动画确实 运行,但只有一次。我之前没有看到它,因为 window 开始最小化。
为什么触发事件发生多少次都只运行一次?
这仅设置设计时数据上下文:
d:DataContext="{d:DesignInstance local:ItineraryViewModel}"
当您实际 运行 应用程序时,这不会有任何影响。
您应该将视图的 DataContext
属性 设置为视图模型的实例:
<Window ...>
<Window.DataContext>
<local:ItineraryViewModel />
</Window.DataContext>
我最终是这样解决问题的:
private void ShowInfocenterIfAnyItinirary(object sender, ElapsedEventArgs e)
{
if (Items.Count <= 0) return;
GlobalEvents.TriggerShowMainWindowEvent();
ViewEventTrigger = "True";
Task.Run(async () =>
{
Thread.Sleep(4000);
ViewEventTrigger = "False";
});
}
这会停止动画,而不是让它在结束点暂停。
在我的视图模型中,我有一个计时器需要每 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 来测试它。但是我无法通过将它绑定到我的 属性.
来使其工作编辑:
我这样设置数据上下文:
d:DataContext="{d:DesignInstance local:ItineraryViewModel}"
此外,我还有很多其他数据绑定可以正常工作,例如要显示的数据和按钮命令。但是我就是不能让触发器执行故事情节。
方法ShowInfocenterIfAnyItinirary()
由计时器执行,在视图模型中启动。
定时器代码:
private readonly Timer _timer = new Timer();
public ItineraryViewModel()
{
_timer.Interval = 5000;
_timer.Elapsed += ShowInfocenterIfAnyItinirary;
_timer.Start();
}
编辑 2:
我已经延迟了动画应该在程序 运行 时开始。我发现动画确实 运行,但只有一次。我之前没有看到它,因为 window 开始最小化。
为什么触发事件发生多少次都只运行一次?
这仅设置设计时数据上下文:
d:DataContext="{d:DesignInstance local:ItineraryViewModel}"
当您实际 运行 应用程序时,这不会有任何影响。
您应该将视图的 DataContext
属性 设置为视图模型的实例:
<Window ...>
<Window.DataContext>
<local:ItineraryViewModel />
</Window.DataContext>
我最终是这样解决问题的:
private void ShowInfocenterIfAnyItinirary(object sender, ElapsedEventArgs e)
{
if (Items.Count <= 0) return;
GlobalEvents.TriggerShowMainWindowEvent();
ViewEventTrigger = "True";
Task.Run(async () =>
{
Thread.Sleep(4000);
ViewEventTrigger = "False";
});
}
这会停止动画,而不是让它在结束点暂停。