2013-05-29 64 views
0

我試圖在用戶嘗試在我的表單中執行非法操作時實施警告系統。這個想法是調用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

回答

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

UPDATE:爲了延緩拆除的消息,你當然可以用一個定時器。也許你可以寫你的StatusBarFade方法類似如下所示,用DispatcherTimer

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

所以我會在創建動畫構造函數,然後更改StatusBarFade方法中的statusBar.Foreground屬性? 據我所看到的,這會閃爍一秒半的文本,然後刪除文本,將不是嗎?我需要文字閃爍1.5秒,然後在移除之前保留另一個X(大概3秒)。我可以創建一個複合動畫,或者我應該簡單地使用這個動畫結合定時器用於去除上面的代碼的文本? – user2352164

+0

請參閱我的編輯,瞭解如何編寫您的方法的建議。 – Clemens

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

@克萊門斯的回答是你在找什麼。我只是想找出這種行爲的原因。

您遇到的問題是由於在定時器迭代完成後附加委託而不刪除它們的事實。

因此,爲什麼你看到每一個甚至出現此行爲,因爲在偶數代表的是連接到定時器的經過事件的時間,從而它幾乎增加的增量2,4,6,...這樣結束了從黑色 - >黑色,我們從來沒有看到切換到黃金。動畫的總體時間也以相同的方式逐漸下降。這是問題。

修復了,這將是(請不要使用這個,只是把它作爲一個案例。使用@Clemens方法或直接有故事板在XAML)

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