WPF故事板只在第一次调用时触发
本文关键字:调用 第一次 故事 WPF | 更新日期: 2023-09-27 17:54:39
我一直试图在控件中显示一条消息,当我收到一条消息说我已发布的更新已成功接收时,该消息仅出现几秒钟。
我有一个类实现INotifyPropertyChanged如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace Wpf.GUI.Views
{
public class AlertBarStatus : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public event RoutedEventHandler VisibleChanged;
private bool _visible ;
private bool _success ;
public AlertBarStatus():this (false,false)
{
}
public AlertBarStatus(bool visible, bool success)
{
_visible = visible;
_success = success;
}
public bool Visible
{
get { return _visible; }
set
{
_visible = value;
OnPropertyChanged("Visible");
if(VisibleChanged != null)
{
VisibleChanged(this, null);
}
}
}
public bool Success
{
get { return _success; }
set
{
_success = value;
OnPropertyChanged("Success");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我有xaml,它包含如下控件:
<UserControl x:Class="Wpf.GUI.AlertBarControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Border x:Name="alertStatusBorder" Height="50" Visibility="Collapsed" Opacity="0" HorizontalAlignment="Stretch" >
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding AlertBarStatus.Success}" Value="True">
<Setter Property="Background" Value="{StaticResource EnabledBorderBackground}" />
</DataTrigger>
<DataTrigger Binding="{Binding AlertBarStatus.Success}" Value="False">
<Setter Property="Background" Value="{StaticResource DisabledBorderBackground}" />
</DataTrigger>
<DataTrigger x:Name="VisibilityTrigger" Binding="{Binding AlertBarStatus.Visible}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard x:Name="VisibilityStoryboard">
<ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0" To="100" Duration="0:0:5" />
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="100" To="0" Duration="0:0:5" />
<ObjectAnimationUsingKeyFrames Duration="0:0:5" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="VisibilityStoryboard"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<DockPanel >
<TextBlock DockPanel.Dock="Left" x:Name="alertStatusText" Grid.Column="0" HorizontalAlignment="Left">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding AlertBarStatus.Success}" Value="True">
<Setter Property="Text" Value="Successfully published updates" />
</DataTrigger>
<DataTrigger Binding="{Binding AlertBarStatus.Success}" Value="False">
<Setter Property="Text" Value="Failed to publish updates" />
</DataTrigger>
</Style.Triggers>
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="VerticalAlignment" Value="Center"></Setter>
</Style>
</TextBlock.Style>
</TextBlock>
<!--<Button Height="20" Width="20" Margin="3" DockPanel.Dock="Right" HorizontalAlignment="Right"
Background="Transparent" BorderBrush="Black"
Click="CloseAlertControl_Click">X</Button>-->
</DockPanel>
</Border>
</Grid>
名为visbilitytrigger的DataTrigger做了我想要的,但只有当成功值第一次改变时。然后不再调用它。
我知道这个问题有几种不同的答案,但我已经尝试了我能找到的所有解决方案,但到目前为止,它们都不适合我。
为了澄清,可见性属性可以设置为true多次之前,它设置为false,因此我在想,也许这可能是问题,因为我没有设置值为不同的值,但我可以看到OnProperty改变的方法被调用,所以我不希望这是一个问题。
任何帮助在这将是非常感激!
最后,我放弃了在xaml中尝试这样做,而是将对象的可见性绑定到底层对象的可见性属性,如下所示。
<Border x:Name="alertStatusBorder" Height="50" Visibility="{Binding Path=AlertBarStatus.Visible, Converter={StaticResource BoolToVis}}">
然后我使用了一个计时器,事件在10秒后触发,将可见性变量设置为false,并禁用定时器,这就像一个魅力。
定时器代码:
Timer _alertBarTimer = new Timer(10000);
_alertBarTimer.Elapsed += _alert_timer_elapsed;
private void _alert_timer_elapsed(object sender, ElapsedEventArgs e)
{
alertBarControl.AlertBarStatus.Visible = false;
_alertBarTimer.Enabled = false;
}
设置可见性的代码:
alertBarControl.AlertBarStatus.Visible = true;
_alertBarTimer.Enabled = true;
这可能不是最好的方法,但它肯定不是最坏的,因为我没有直接在代码中设置控件的属性,而是使用绑定到控件的对象。
如果有人有更好的方法,请随时贡献:)