【问题标题】:Blinking text in status bar状态栏中的闪烁文本
【发布时间】:2013-05-29 14:01:14
【问题描述】:

当用户尝试在我的表单中执行非法操作时,我正在尝试实施警告系统。这个想法是调用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

【问题讨论】:

    标签: c# wpf timer statusbar


    【解决方案1】:

    您可以简单地使用以下动画:

    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();
    }
    

    【讨论】:

    • 所以我会在构造函数中创建动画,然后在 StatusBarFade 方法中更改 statusBar.Foreground 属性?据我所知,这会使文本闪烁一秒钟半,然后删除文本,不是吗?我需要文本闪烁 1.5 秒,然后再停留 X(可能 3)秒,然后再被删除。我可以创建一个复合动画,还是应该简单地将此动画与用于删除上述代码中的文本的计时器结合使用?
    【解决方案2】:

    尝试使用故事板。

    <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>
    

    【讨论】:

      【解决方案3】:

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

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

      因此,为什么您会在每次偶数事件中看到这种行为,因为在那些时候,偶数个委托被附加到计时器的经过事件,因此它几乎以 2、4、6 的增量增加,......因此最终会从黑色 -> 黑色,我们永远不会看到切换到金色。动画的总时间也以同样的方式逐渐下降。这就是问题所在。

      解决这个问题(请不要使用它。将其视为一个案例。使用@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;
            })));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-17
        • 1970-01-01
        • 2021-06-26
        • 1970-01-01
        • 1970-01-01
        • 2017-03-08
        • 1970-01-01
        • 2012-08-04
        相关资源
        最近更新 更多