2015-08-16 70 views
4

表面上看起來很簡單。 我有一個開關盒,如果條件滿足,我想用動畫將文本打印到標籤上。在這種情況下爲 是一種類型寫作者動畫。開關盒內的標籤動畫c#

我已經做了動畫,但我似乎無法將類似的版本集成到開關盒中。 有什麼幫助嗎?

打字機動畫代碼C#:

public partial class Form1 : Form 
{ 
    int _charIndex = 0; 
    string _text = "This is a test."; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     _charIndex = 0; 
     label1.Text = string.Empty; 
     Thread t = new Thread(new ThreadStart(this.TypewriteText)); 
     t.Start(); 
    } 


    private void TypewriteText() 
    { 
     while (_charIndex < _text.Length) 
     { 
      Thread.Sleep(50); 
      label1.Invoke(new Action(() => 
      { 
       label1.Text += _text[_charIndex]; 
      })); 
      _charIndex++; 
     } 
    } 

} 

}

,需要放入此動畫代碼:

開關箱代碼:

 void TestEngine(object sender, SpeechRecognizedEventArgs e) 
    { 
     switch (e.Result.Text) 
     { 
      case "Test": 
      //Label animation code goes here 
      break; 

謝謝提前!

+2

附註:永遠不要使用'Thread.Sleep(50);'來延遲。而是使用'Task.Delay(50).Wait();' –

+1

你確定'e.Result.Text'曾經評估過「Test」嗎? –

+2

@ M.kazemAkhgary:不,不要使用'等待' - 使用'等待Task.Delay(50)'或者使用'Timer'。 'Waiit()'是一個*阻塞*調用,使其更像'Thread.Sleep'。 –

回答

2

簡短的答案 - 移動方法中的代碼,並從任何你想要的地方調用它。
長答案
雖然它的工作,它沒有意義,因爲所有的工作線程都在睡覺,然後調用UI線程。基於方法的方法對於這個具體情況將非常合適。 「現代」方法將基於async/await。如果你需要靈活性,最後一個是最好的選擇。但是無論你選擇什麼,你都會在某個時候遇到重入問題並需要處理。最好的做法是準備一些輔助工具類,並在任何地方使用它。下面是一個例子:

using System; 
using System.Drawing; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Tests 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new TestForm()); 
     } 

     class TestForm : Form 
     { 
      public TestForm() 
      { 
       var label = new Label { Parent = this, AutoSize = true, Top = 8, Left = 8 }; 
       animateHelper = new AnimateHelper(label); 
       int left = 8; 
       foreach (var action in (ButtonAction[])Enum.GetValues(typeof(ButtonAction))) 
       { 
        var button = new Button { Parent = this, AutoSize = true, Text = action.ToString(), Left = left }; 
        button.Top = DisplayRectangle.Bottom - button.Height - 8; 
        button.Click += (sender, e) => Execute(action); 
        left += button.Width + 8; 
       } 
      } 
      protected override void Dispose(bool disposing) 
      { 
       if (disposing && animateHelper != null) animateHelper.Cancel(); 
       base.Dispose(disposing); 
      } 
      enum ButtonAction { TypewriteText, RepeatText, Cancel } 
      private void Execute(ButtonAction action) 
      { 
       // the original question 
       switch (action) 
       { 
        case ButtonAction.TypewriteText: 
         TypewriteText("This is a typewriter text animantion test."); 
         break; 
        case ButtonAction.RepeatText: 
         RepeatText("This is a repeating text animantion test."); 
         break; 
        case ButtonAction.Cancel: 
         animateHelper.Cancel(); 
         break; 
       } 
      } 
      AnimateHelper animateHelper; 
      void TypewriteText(string text) 
      { 
       animateHelper.Execute(async (output, ct) => 
       { 
        bool clear = true; 
        try 
        { 
         if (string.IsNullOrEmpty(text)) return; 
         output.ForeColor = Color.Blue; 
         for (int length = 1; ; length++) 
         { 
          if (ct.IsCancellationRequested) return; 
          output.Text = text.Substring(0, length); 
          if (length == text.Length) break; 
          await Task.Delay(50, ct); 
         } 
         clear = false; 
        } 
        finally { if (clear) output.Text = string.Empty; } 
       }); 
      } 
      void RepeatText(string text) 
      { 
       animateHelper.Execute(async (output, ct) => 
       { 
        try 
        { 
         if (string.IsNullOrEmpty(text)) return; 
         output.ForeColor = Color.Red; 
         while (true) 
         { 
          for (int length = 1; length <= text.Length; length++) 
          { 
           if (ct.IsCancellationRequested) return; 
           output.Text = text.Substring(text.Length - length); 
           await Task.Delay(50, ct); 
          } 
          for (int pad = 1; pad < text.Length; pad++) 
          { 
           if (ct.IsCancellationRequested) return; 
           output.Text = new string(' ', pad) + text.Substring(0, text.Length - pad); 
           await Task.Delay(50, ct); 
          } 
          if (ct.IsCancellationRequested) return; 
          output.Text = string.Empty; 
          await Task.Delay(250, ct); 
         } 
        } 
        finally { output.Text = string.Empty; } 
       }); 
      } 
     } 

     class AnimateHelper 
     { 
      Label output; 
      Task task; 
      CancellationTokenSource cts; 
      public AnimateHelper(Label output) { this.output = output; } 
      void Reset() 
      { 
       if (cts != null) { cts.Dispose(); cts = null; } 
       task = null; 
      } 
      public void Cancel() { DontCare(CancelAsync()); } 
      async Task CancelAsync() 
      { 
       if (task != null && !task.IsCompleted) 
       { 
        try { cts.Cancel(); } catch { } 
        try { await task; } catch { } 
       } 
       Reset(); 
      } 
      public void Execute(Func<Label, CancellationToken, Task> action) { DontCare(ExecuteAsync(action)); } 
      async Task ExecuteAsync(Func<Label, CancellationToken, Task> action) 
      { 
       await CancelAsync(); 
       cts = new CancellationTokenSource(); 
       task = action(output, cts.Token); 
       try { await task; } catch { } 
       Reset(); 
      } 
      // make compiler happy 
      static void DontCare(Task t) { } 
     } 
    } 
} 
+0

非常感謝!被幫助的公用事業班完美運作。 – 15hjArray