Использование таймера и миллисекунд для исчезновения формы, но продолжительность удваивается - PullRequest
0 голосов
/ 17 сентября 2018

Я создаю свое собственное маленькое настраиваемое окно сообщения, по сути, это просто маленькое окно, которое отображается с сообщением в течение 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;
        }
    }

1 Ответ

0 голосов
/ 17 сентября 2018

Если пользователь устанавливает интервал замирания равным 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, showTimer и fadeTimer):

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();
}
...