我一直试图在控件中显示一条消息,当我收到一条消息说我已经成功收到我发布的更新时,该消息只会出现几秒钟。
我有一个实现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>
名为VisibilityTrigger的DataTrigger完全符合我的要求,但仅当Success值第一次更改时才会执行。它不会再被调用。
我知道这个问题有几个不同的答案,但我已经尝试了所有可以找到的解决方案,但到目前为止,它们都不适用于我。
为了澄清,可见性属性可以在设置为false之前多次设置为true,因此我认为这可能是问题,因为我没有将值设置为不同的值,但我可以看到正在调用OnProperty更改的方法,所以我不希望这是一个问题。
对此有任何帮助将不胜感激!
答案 0 :(得分:0)
最后,我放弃尝试在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;
这可能不是最好的方法,但它肯定不是最糟糕的,因为我没有直接在代码中设置控件的属性,而是使用绑定到控件的对象。
如果有人有更好的方法,请随时提供:)