在开关盒内标记动画c#

时间:2015-08-16 16:24:10

标签: c# animation types switch-statement case

从表面上看似乎很简单。 我有一个开关盒,如果满足条件,我想将文本打印到带动画的标签上。 在这种情况下是一种类型的作家动画。

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

键入Writer动画代码c#:

t

}

动画代码需要放入:

切换案例代码:

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

}

提前致谢!

1 个答案:

答案 0 :(得分:2)

简短回答 - 在方法中移动代码并从任何您想要的地方调用它 答案很长
虽然它有效,但它没有意义,因为所有工作线程都在休眠,然后调用UI线程。基于System.Windows.Forms.Timer的方法对于这个具体案例来说非常合适。 &#34;现代&#34;方法将基于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) { }
        }
    }
}