c# - 开关盒 c# 内的标签动画

标签 c# animation types switch-statement case

从表面上看,这似乎很简单。 我有一个开关盒,如果满足条件,我想将文本打印到带有动画的标签上。 在本例中是打字机动画。

我已经制作了动画,但是我似乎无法将类似的版本集成到开关盒本身中。 有帮助吗?

Type Writer 动画代码 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;

提前致谢!

最佳答案

简答 - 将代码移动到一个方法中,然后从任何你想要的地方调用它。
长答案
虽然它有效,但它没有意义,因为工作线程所做的只是休眠,然后调用 UI 线程。基于 System.Windows.Forms.Timer 的方法非常适合这种具体情况。 “现代”方法将基于 async/await。如果你需要灵 active ,最后一个是最好的选择。但是无论您选择什么,您都会在某个时候遇到重入问题并且需要处理它。最好的办法是准备一些辅助实用程序类并在任何地方使用它。这是一个例子:

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

关于c# - 开关盒 c# 内的标签动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32037373/

相关文章:

c# - 在 C# 中通过 COM Interop 编码字符串时编码失败(双 UTF8 编码?)

c# - 单击wpf中的RepeatButton时如何将光标聚焦在文本框中?

c# - 新窗体上的 STAThread 错误(SaveFileDialog)

ios - 使 SDWebImage 出现动画淡入淡出

python - numpy.isnan(value) 与 value == numpy.nan 不同吗?

c# - 是否可以动态地将事件添加到 XAML 中的按钮?

javascript - 使用 css transitions 动画 flexbox 的问题

android - fab.show() 在初始化新 Activity 后第一次没有动画

python - 扩展 Python 的 int 类型以仅接受给定范围内的值

c++ - 如何在 C++ 中实现公式模式?