【发布时间】:2021-11-28 13:00:53
【问题描述】:
我有一个 MVVM 模式应用程序,我希望用户能够在其中输入日期,但也可以在这些日期上应用一些验证。我通过检查他们输入的任何内容并用最近的有效日期覆盖它来做到这一点,如果他们的输入无效。为了让用户知道他们的日期已被覆盖,我会尝试为日期选择器文本框的前景设置动画,但我发现动画仅在他们的日期第一次以这种方式“更正”时可见.
在 MainViewModel 中,我有一个 Ping 属性,每次设置为“true”时都会通知 UI,还有一个验证方法,每次必须覆盖日期时设置 Ping = true:
public bool Ping
{
get => _ping;
set
{
if (value && !_ping)
{
_ping = value;
OnPropertyChanged();
_ping = false;
}
}
}
private DateTime _from;
//Bound to the Date input field in the UI
public DateTime From
{
get { return _from; }
set
{
if (_from != value)
{
_from = giveValidDate("From", value);
OnPropertyChanged();
}
}
}
private DateTime giveValidDate(string posn, DateTime givenDate)
{
DateTime validDate = new DateTime();
// [...A Load of validation that results in a valid Date output...] //
Ping = givenDate != validDate;
return validDate;
}
我正在使用一种带有动画的 TextBox 样式:
<Style x:Key="PingableTextBox" TargetType="TextBox">
<Setter Property="TextBlock.FontSize" Value="18"/>
<Setter Property="TextElement.FontSize" Value="18"/>
<Setter Property="TextElement.Foreground" Value="{StaticResource Text_LightBrush}"/>
<Setter Property="TextElement.FontWeight" Value="Normal"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="2"
BorderBrush="{StaticResource Highlight_LightBrush}"
Background="{StaticResource Empty_DarkBrush}"
x:Name="border"
SnapsToDevicePixels="True">
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
Name="PART_ContentHost" Focusable="False" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="Border.BorderBrush" TargetName="border" Value="{StaticResource Good_MidBrush}"/>
<Setter Property="Cursor" Value="IBeam"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Ping}" Value="true">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="Pinger"/>
<BeginStoryboard Name="Pinger">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
From="{StaticResource Bad_Bright}" To="{StaticResource Text_Light}" FillBehavior="Stop"
Duration="0:0:0:1.0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="Pinger"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
但是,当我运行该应用程序时,触发器只能看到一次(选择无效日期时短暂的红色闪烁):
我在 Stack Overflow 上看到过很多其他关于同一问题的问题,但解决方案一直是在 Enter Actions 中添加行 <StopStoryboard BeginStoryboardName="Pinger"/>,在 Exit Actions 中添加行 <RemoveStoryboard BeginStoryboardName="Pinger"/> 或添加 @ 987654332@ 到故事板。我已经在我能想到的所有地方尝试了这些中的每一种组合,但问题仍然存在。
对于我可能错过的问题是否有其他解释可以为我解决它,或者我未能正确实施的问题。简而言之,为什么它只触发一次?
PS - 我用来实现您在上面看到的代码的一些问题:
WPF Storyboard only fires once
WPF Fade In / Out only runs once
【问题讨论】:
标签: c# wpf animation datatrigger