Помогите поправить алгоритм на C#

281
06 октября 2017, 14:21

Здравствуйте! Я недавно начал изучать C#. Помогите, пожалуйста, поправить алгоритм. Идея такая: у меня есть Кнопка с надписью "Start" и Панель, на которой нарисован шарик в точке (0, 0); он не движется. Но заданы его скорости (double dx, dy). При нажатии на кнопку надпись на ней меняется на "Stop", шарик начинает двигаться с заданными скоростями. При повторном нажатии шарик останавливается (делаю это через приравнивание скоростей нулю и сохранение скоростей в переменных olddx, olddy; если подскажете, как остановить System.Threading.Timer, буду совсем благодарен), а надпись на кнопке меняется на "Start". И так далее: шарик запускается/останавливается и меняется надпись на кнопке. Вот код:

int time = 0;
bool flagmove = false;
private void button1_Click(object sender, EventArgs e)
{
    double olddx = 0;
    double olddy = 0;
    TimerCallback tc = new TimerCallback (updateCoords);
    System.Threading.Timer timer;
    if (flagMove == false) { // Если шарик не движется
        flagMove = true;
        if (time != 0) {
            dx = olddx;
            dy = olddy;
        }
        if (time == 0) // Таймер создаём лишь однажды
            timer = new System.Threading.Timer (tc, time++, 0, 10);
        ((Button)sender).Text = "Stop";
    } else { // Если движется
        flagMove = false;
        ((Button)sender).Text = "Start";
        olddx = dx; // Ощущение, как будто эти две
        olddy = dy; // строки не выполняются.
        dx = 0;
        dy = 0;
    }
}

Что реально происходит: надпись на кнопке меняется, как я и ожидал. Шарик в первый раз запускается, потом останавливается и больше не запускается (как будто olddx и olddy как были инициализированы нулями, так ими и остаются). Скажите, пожалуйста, что делать. Идеальный вариант - это не шаманство с olddx, olddy, а остановка таймера, но я не понимаю, как это делать.

Добавлено: Использую WinForms.

Answer 1

Используйте класс Timer из пространства имен System.Timers - у него есть удобные методы Start()/Stop() и еще более удобное свойство Enabled, можно запускать/останавливать таймер просто инвертируя его:

timer.Enabled = !timer.Enabled;

Также я рекомендую вынести создание таймера в конструктор формы, тогда не придется проверять создан ли он уже или еще нет:

System.Timers.Timer timer;
public Form1()
{
    InitializeComponent();
    timer = new System.Timers.Timer();
    timer.Elapsed += updateCoords;
}

Также в вашем коде не видно где вы перезаписываете значение переменной time, поэтому вы каждый раз создаете новый таймер. В моем варианте она вам не нужна.

А вообще в Windows Forms есть свой таймер, расположенный в пространстве имен System.Windows.Forms (у вас ведь WinForms? На будущее - указывайте соответствующий тег в вопросе), вы можете использовать его, разница в том, что событие у него называется Tick, свойство Enabled у него работает аналогично. И я вам рекомендую использовать именно этот таймер, так как он запускает обработчики событий в потоке UI, другие таймеры нужно проверять, но это выходит за рамки этого ответа.

READ ALSO
Как можно обрезать строку?

Как можно обрезать строку?

Допустим есть строка в listBox "UserFIrstName UserLastName 21993842"Как обрезать эту строку, чтобы осталось "UserFIrstName" или "UserFIrstName UserLastName"?

373
Вызвать static конструктор без обращений к классу

Вызвать static конструктор без обращений к классу

Возможно ли, какими нибудь окольными путями (меняя код в рамках одного класса Test), заставить программу на старте вызывать статик конструктор...

314
C# - Сравнивание времени(DataTime)

C# - Сравнивание времени(DataTime)

Всем приветСтолкнулся с проблемой

201