2015-08-16 40 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