在状态栏中闪烁文本

时间:2013-05-29 14:01:14

标签: c# wpf timer statusbar

我正在尝试在用户尝试在表单中执行非法操作时实施警告系统。我的想法是调用StatusBarFade方法,给它应该写的参数,而不是让方法显示文本,通过改变它的颜色让它眨眼一秒半,然后再保持一秒半之后文本将消失。

每隔一段时间闪烁一次,而文字正常消失。

请注意,我知道这段代码非常混乱,肯定有更好的方法,但由于我不知道代理如何工作,我不知道如何正确使用它们。希望有人能够解释我做错了什么。无论如何,经过一些测试我意识到最好有两个计时器。问题是这段代码每隔一段时间就有效。

    private Timer timer = new System.Timers.Timer();
    private Timer timerColor = new System.Timers.Timer();
    private void StatusBarFade(string ispis)
    {
        statusBar1AS2.Content = ispis;
        int i = 0;
        timerColor.Interval = 100;
        timerColor.AutoReset = true;
        timerColor.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    ++i;
                    if (statusBar1AS2.Foreground == Brushes.Black)
                        statusBar1AS2.Foreground = Brushes.Gold;
                    else
                        statusBar1AS2.Foreground = Brushes.Black;
                    if (i > 15)
                    {
                        statusBar1AS2.Foreground = Brushes.Black;
                        i = 0;
                        timerColor.Stop();
                    }
                }));
        };
        timerColor.Start();

        timer.Interval = 3000;
        timer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e)
        {
            timer.Stop();
            this.Dispatcher.BeginInvoke(new Action(() => { statusBar1AS2.Content = ""; }));
        };
        timer.Start();
    }

据我了解委托,我不应该在每次更改文本时将相同的委托添加到timer.Elapsed事件,而是在构造函数中仅添加一次,例如。问题是我不知道如何以我在代码中的方式使用计数器i

3 个答案:

答案 0 :(得分:4)

您只需使用以下动画:

var animation = new ColorAnimation
{
    From = Colors.Black,
    To = Colors.Gold,
    AutoReverse = true,
    Duration = TimeSpan.FromSeconds(0.1),
    RepeatBehavior = new RepeatBehavior(TimeSpan.FromSeconds(1.5))
};

animation.Completed += (o, e) => statusBar.Content = string.Empty;

statusBar.Foreground = new SolidColorBrush();
statusBar.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, animation);

更新:为了延迟删除邮件,您当然可以使用计时器。您可以使用DispatcherTimer

编写如下所示的StatusBarFade方法
private void StatusBarFade(string message)
{
    statusBar.Content = message;

    var animation = new ColorAnimation
    {
        From = Colors.Gold,
        To = Colors.Black,
        AutoReverse = true,
        Duration = TimeSpan.FromSeconds(0.1),
        RepeatBehavior = new RepeatBehavior(TimeSpan.FromSeconds(1.5)),
    };

    statusBar.Foreground = new SolidColorBrush();
    statusBar.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, animation);

    var timer = new DispatcherTimer
    {
        Interval = TimeSpan.FromSeconds(4.5)
    };

    timer.Tick +=
        (o, e) =>
        {
            timer.Stop();
            statusBar.Content = string.Empty;
        };

    timer.Start();
}

答案 1 :(得分:0)

尝试使用故事板。

<Storyboard x:Key="TestBlinkStoryboard" AutoReverse="True" RepeatBehavior="Forever">
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="textBlock">
            <EasingColorKeyFrame KeyTime="0" Value="Black"/>
            <EasingColorKeyFrame KeyTime="0:0:0.5" Value="#FFE91414">
                <EasingColorKeyFrame.EasingFunction>
                    <BounceEase EasingMode="EaseInOut"/>
                </EasingColorKeyFrame.EasingFunction>
            </EasingColorKeyFrame>
        </ColorAnimationUsingKeyFrames>
    </Storyboard>

答案 2 :(得分:0)

@ Clemens的答案就是你要找的。我只想找出这种行为的原因。

您遇到的问题是由于在完成计时器的迭代后附加委托而不删除它们的事实。

因此,为什么你会在每一次偶然事件中看到这种行为,因为在那些时候偶数个代表被附加到计时器的已经过去的事件上,因此它以2,4,6的增量几乎增加,......因此最终从黑色 - &gt;黑色,我们从未看到转向黄金。动画的整体时间也以同样的方式逐渐下降。那就是问题。

修复即可(请不要使用此功能。只需将其视为案例。使用@Clemens方法或直接在xaml中使用Storyboard)

private int i = 0;

private void StatusBarFade(string ispis) {
  i = 0;
  statusBar1AS2.Content = ispis;
  timerColor.Interval = 100;
  timerColor.AutoReset = true;
  timerColor.Elapsed += TimerColorOnElapsed;
  timerColor.Start();
}

private void TimerColorOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) {
  Dispatcher.BeginInvoke(
    (new Action(
      () => {
        ++i;
        statusBar1AS2.Foreground = i % 2 == 0 || i > 15 ? Brushes.Black : Brushes.Gold;
        if (i < 30)
          return;
        timerColor.Stop();
        timerColor.Elapsed -= TimerColorOnElapsed;
        statusBar1AS2.Content = string.Empty;
      })));
}