我有一個 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>
However, when I run the application, the trigger is only seen to act once (the brief red flash when an invalid date is selected):

I have seen many other questions on Stack Overflow about the same issue, but the solution has always been to add the line <StopStoryboard BeginStoryboardName="Pinger"/> in the Enter Actions, to add the line <RemoveStoryboard BeginStoryboardName="Pinger"/> to the Exit Actions or to add FillBehavior="Stop" to the storyboard. I have tried every combination of each of these in all places I could think of and the problem still persists.
Is there some other explanation for the problem that I could have missed that would fix it for me, or something that I have failed to implement correctly.. In short, why is it only firing once?
PS - some of the questions I have used to implement the code you see above:
WPF Storyboard only fires once
WPF Fade In / Out only runs once
Tag 屬性上的 WPF MultiDataTrigger 僅觸發一次
WPF - DataTrigger 的問題,它只作業一次
uj5u.com熱心網友回復:
您必須PropertyChanged在重置Ping屬性后引發 ,才能觸發Trigger.ExitAction.
設定支持欄位_ping不會將任何更改通知傳播到視圖。
這意味著您的問題不是您參考的答案試圖解決的問題。
您也不應該Trigger.ExitAction在您的場景中定義。由于您已將影片配置為在時間線完成后自動停止 ( FillBehavior="Stop"),因此您無需執行任何操作即可停止。請注意,RemoveStoryboard這對您的情況沒有任何幫助。它只會使重置屬性的邏輯復雜化,因為RemoveStoryboard會在即時屬性切換時立即終止影片。這意味著,避免Trigger.ExitAction或者 更準確地說,RemoveStoryboard允許您立即切換屬性:
// Trigger the animation
Ping = givenDate != validDate;
// Reset the property immediately to reset the animation trigger.
// Because the `Trigger.ExitAction` is deleted,
// the currently running animation will complete the timeline.
Ping = false;
如果要更優雅實作邏輯可以切換Ping特性并定義Trigger.EnterAction為true狀態和Trigger.ExitAction用于false狀態(因此每一個狀態轉換為驗證錯誤信號):
public bool Ping
{
get => _ping;
set
{
if (value && !_ping)
{
_ping = value;
OnPropertyChanged();
}
}
}
private DateTime giveValidDate(string posn, DateTime givenDate)
{
DateTime validDate = new DateTime();
// [...A Load of validation that results in a valid Date output...] //
// Trigger the animation by toggling the property.
if (givenDate != validDate)
{
Ping ^= true;
}
return validDate;
}
<DataTrigger Binding="{Binding Ping}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<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>
<BeginStoryboard>
<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.ExitActions>
</DataTrigger>
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/315334.html
上一篇:在R中影片直方圖
