首页 > 解决方案 > 使用计时器和毫秒来淡出表格,但持续时间加倍

问题描述

我正在制作自己的小自定义消息框,本质上它只是一个小框,显示一条消息 X 时间,然后消失 Y 持续时间。正在发生的事情是,褪色需要的时间是预期的两倍,我不知道为什么。有人可以查看我的代码并发现为什么淡出表单所需的时间比预期的要多一倍吗?

    //Initiate and set up the message bubble.
    public static void InitiateBubble(String displayText, Double showTime = 1000, Double fadeTime = 2000) {
        Bubble bubble = new Bubble(displayText);
        bubble.showTime = showTime;
        bubble.fadeTime = fadeTime;
        bubble.Show();
        bubble.showTimer = new Timer();
        bubble.showTimer.Interval = (int)bubble.showTime;
        bubble.showTimer.Tick += bubble.startFadeAway;
        bubble.showTimer.Start();
    }

    //Leaves some time on screen before starting to fade away
    private void startFadeAway(object sender, EventArgs e) {
        showTimer.Stop();
        fadeAwayTimer = new Timer();
        fadeAwayTimer.Interval = 10;
        fadeAwayTimer.Tick += fadeAway;
        fadeAwayTimer.Start();
    }

    //slowly fades the contorle away until it disapears.
    private void fadeAway(object sender, EventArgs e) {
        double opacity = Opacity;
        opacity -= (10 / fadeTime);
        if (opacity < 0) {
            Close();
        }
        else {
            Opacity = opacity;
        }
    }

标签: c#timerfade

解决方案


如果用户将淡化间隔设置为 1 秒(1000 毫秒),而我们将计时器间隔设置为 1/10 秒(100 毫秒),那么我们需要每个间隔将不透明度淡化 10%(因为间隔为每秒触发 10 次)。所以我们会Opacity -= .1在每次迭代中设置。

如果用户将淡入淡出间隔设置为 2 秒(2000 毫秒),而我们仍然将计时器间隔设置为 1/10 秒,那么我们只需将不透明度每间隔淡化 5%,因此我们将设置Opacity -= .05为每次迭代。

看到这个关系,我们可以发现:

var amountToReduceOpacity = 1.0 / fadeTime * interval;

注意: 正如上面提到的 γηράσκω δ' αεί πολλά διδασκόμε,winform 计时器的分辨率约为 17 毫秒,因此如果我们将其设置为小于此值,淡入淡出将显着减慢,因为我们将计算出非常快的速率计时器(意味着我们不会在每次迭代中褪色太多),但它会执行得更慢。在我的机器上,将其设置为50看起来就好了。

现在我们可以使用这个公式在每个间隔中始终以正确的量淡化表格。这是一个示例Form,它基本上完成了您在上面所做的工作(请注意,我在表单上放置了一个标签和两个计时器,并将它们命名为:lblDisplay、、showTimerfadeTimer):

public partial class Bubble : Form
{
    private readonly double amountToReduceOpacity;
    private readonly int fadeInterval = 50; 

    // Custom form constructor takes in all three required settings
    public Bubble(string displayText, int showTime, int fadeTime)
    {
        InitializeComponent();

        lblDisplay.AutoSize = true;
        lblDisplay.Text = displayText;
        lblDisplay.Left = ClientRectangle.Width / 2 - lblDisplay.Width / 2;
        lblDisplay.Top = ClientRectangle.Height / 2 - lblDisplay.Height / 2;

        showTimer.Interval = showTime;
        fadeTimer.Interval = fadeInterval;

        amountToReduceOpacity = 1.0 / fadeTime * fadeInterval;
    }

    // The Shown event starts the first timer
    private void Bubble_Shown(object sender, EventArgs e)
    {
        showTimer.Start();
    }

    // The shownTimer starts the fadeTimer
    private void showTimer_Tick(object sender, EventArgs e)
    {
        showTimer.Stop();
        BackColor = Color.Red; // Just so we see when the fade starts
        fadeTimer.Start();
    }

    // The fade timer reduces opacity on each iteration until it's zero
    private void fadeTimer_Tick(object sender, EventArgs e)
    {
        Opacity -= amountToReduceOpacity;
        if (Opacity <= 0) Close();            
    }
}

然后在客户端,我们可以执行以下操作:

private void button1_Click(object sender, EventArgs e)
{
    Bubble bubble = new Bubble("Help me, I'm Fading!", 1000, 2000);
    bubble.Show();
}

推荐阅读